for和foreach有什么区别?

24

for循环和foreach循环的主要区别是什么?

在哪些情况下我们可以使用for而不能使用foreach,反之亦然。

能否用一个简单的程序来演示?

它们两个看起来都一样。我分不清它们。


3
简短回答:如果迭代顺序很重要,你应该使用for(例如,如果你想向后迭代集合或只想迭代它的每第二个元素),如果迭代顺序不重要,则使用foreach。(顺便说一句,在需要迭代顺序的情况下也可以使用foreach - 在这种情况下,需要重新构造集合。但这会降低程序性能) - Agnius Vasiliauskas
19个回答

2

当您事先确定需要循环运行的次数时,for循环非常有用。例如,如果您需要针对每周的每一天执行某个过程,那么您知道您需要7次循环。

foreach循环是当您想要重复处理集合或数组的所有元素时使用的,但并不重要循环运行的次数具体是多少。例如,您正在为用户格式化一份收藏书籍的列表。每个用户可能拥有不同数量的书籍,或者没有书籍,我们并不关心具体有多少本书,我们只想让循环处理它们所有。


1
在C#中,for循环和foreach循环的主要区别在于它们的工作方式:
for循环: 1. for循环的变量始终为整数。 2. for循环重复执行语句或语句块,直到指定的表达式评估为false。 3. 在for循环中,我们必须指定循环的边界(最大或最小值)。我们可以说这是for循环的限制。
foreach循环: 1. 在foreach循环中,循环的变量与数组中的值类型相同。 2. foreach语句针对数组或对象集合中的每个元素重复一组嵌入式语句。 3. 在foreach循环中,您不需要指定循环边界的最小或最大值。在这里我们可以说这是foreach循环的优势。

1
许多答案已经存在,我只需要找出一个不同之处。
for循环是安全的,而foreach循环是快速失败的。
如果在对象中同时进行迭代和修改,则快速失败迭代会抛出ConcurrentModificationException异常。
然而,安全失败迭代即使迭代进入无限循环,也可以使操作安全。
public class ConcurrentModification {
    public static void main(String[] args) {
        List<String> str = new ArrayList<>();

        for(int i=0; i<1000; i++){
            str.add(String.valueOf(i));
        }

        /**
         * this for loop is fail-safe. It goes into infinite loop but does not fail. 
         */
        for(int i=0; i<str.size(); i++){
            System.out.println(str.get(i));
            str.add(i+ "  " + "10");
        }

        /**
         * throws ConcurrentModificationexception 
        for(String st: str){
            System.out.println(st);
            str.add("10");
        }
        */

        /* throws ConcurrentModificationException 
         Iterator<String> itr = str.iterator();
        while(itr.hasNext()) {
            System.out.println(itr.next());
            str.add("10");
        }*/
    }
} 

希望这有助于从不同角度理解for和foreach循环之间的差异。
我发现一个好的博客来介绍fail-safe和fail-fast之间的区别,如果有人感兴趣:

简单的while循环迭代也是安全的。 - S Kumar

1

就性能而言,我更喜欢使用FOR循环。当您处理更多的项目时,FOREACH会慢一些。

如果您对实例执行更多的业务逻辑,则FOREACH的性能更快。

演示: 我创建了一个包含10000000个实例的列表,并使用FOR和FOREACH进行循环。

循环所需时间:

  • FOREACH -> 53.852毫秒
  • FOR -> 28.9232毫秒

以下是示例代码。

class Program
{

    static void Main(string[] args)
    {
        List<TestClass> lst = new List<TestClass>();
        for (int i = 1; i <= 10000000; i++)
        {
            TestClass obj = new TestClass() {
                ID = i,
                Name = "Name" + i.ToString()
            };
            lst.Add(obj);
        }

        DateTime start = DateTime.Now;
        foreach (var obj in lst)
        {
            //obj.ID = obj.ID + 1;
            //obj.Name = obj.Name + "1";
        }
        DateTime end = DateTime.Now;
        var first = end.Subtract(start).TotalMilliseconds;

        start = DateTime.Now;
        for (int j = 0; j<lst.Count;j++)
        {
            //lst[j].ID = lst[j].ID + 1;
            //lst[j].Name = lst[j].Name + "1";
        }
        end = DateTime.Now;
        var second = end.Subtract(start).TotalMilliseconds;
    }
}

public class TestClass
{
    public long ID { get; set; }
    public string Name { get; set; }
}

如果我取消循环内的代码: 那么,循环所花费的时间为:

  • FOREACH -> 2564.1405毫秒
  • FOR -> 2753.0017毫秒

结论
如果您需要使用更多实例的业务逻辑,则建议使用FOREACH。 如果您不需要使用太多实例的业务逻辑,则建议使用FOR。


欢迎来到SO,我认为如果您能提供一些测试结果来显示它们之间有多大的显着差异,那就更值得了。 - Saeed Zhiany
1
@SaeedZhiany 我更改了我的帖子,因为内容太长。我添加了性能细节和示例。 - Lakshmanan Dhamotharan

0
你可以像这样使用 foreach 循环一个简单的数组:
int[] test = { 0, 1, 2, 3, ...};

当你有一个二维数组时,你可以使用for循环。

int[][] test = {{1,2,3,4},
                {5,2,6,5,8}};

你可以同时使用 for 和/或 foreach 来处理这两种情况。 - James Thorpe

0

for和foreach之间的简单区别

for循环是使用值进行操作的。它必须有条件、递增和初始化。你必须知道“循环重复了多少次”。

foreach循环是使用对象和枚举器进行操作的。不需要知道循环重复了多少次。


0

foreach 语法简单快捷。 for 语法稍微复杂,但也更加灵活。

当迭代集合中的所有项时,foreach 很有用。当迭代整个或子集合中的项时,for 很有用。

foreach 迭代 变量 提供每个集合项,是只读的,因此我们无法在迭代时修改这些项。使用 for 语法,我们可以根据需要修改这些项。

总之- 使用 foreach 快速迭代集合中的所有项。使用 for 迭代集合的子集或在迭代时修改项。


-1
foreach语句用于在数组或实现了System.Collections.IEnumerable或System.Collections.Generic.IEnumerable接口的对象集合中的每个元素上重复一组嵌入式语句。foreach语句用于迭代集合以获取所需信息,但不能用于添加或删除源集合中的项以避免不可预测的副作用。如果需要向源集合添加或删除项,请使用for循环。

-2

foreach 相关的一个重要事项是,在循环体中不能更新(或分配新值)foreach 迭代变量。

例如:

List<string> myStrlist = new List<string>() { "Sachin", "Ganguly", "Dravid" };
              foreach(string item in myStrlist)

              {

                  item += " cricket"; // ***Not Possible*** 

              }


3
实际上你是错的。你的代码结果将会是 { "Sachin cricket", "Ganguly cricket", "Dravid cricket" }。 你不能够添加或移除列表中的任何元素。在循环内调用 myStrlist.Add("Another"); 会引发异常。 - 0wl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接