C# 为什么我可以更改foreach()中的数组元素,但不能更改列表元素? 类程序 { 静态void Main() { int[]arr=新的int[5]{1,2,3,4,5}; 列表=新列表(){1,2,3,4,5}; foreach(内部i在arr中) { arr[2]=7; 控制台写入线(i); } Console.WriteLine(); foreach(列表中的int i) { 列表[2]=7; 控制台写入线(i); } Console.ReadKey(); }

C# 为什么我可以更改foreach()中的数组元素,但不能更改列表元素? 类程序 { 静态void Main() { int[]arr=新的int[5]{1,2,3,4,5}; 列表=新列表(){1,2,3,4,5}; foreach(内部i在arr中) { arr[2]=7; 控制台写入线(i); } Console.WriteLine(); foreach(列表中的int i) { 列表[2]=7; 控制台写入线(i); } Console.ReadKey(); },c#,C#,对集合使用foreach()将获得一个枚举数并重复调用MoveNext() 对于数组,我可以在迭代集合时更改集合中的项 但是,在列表上迭代的代码在第一个循环后抛出异常: 集合已修改;枚举操作可能无法执行 为什么允许数组使用它,而不允许列表使用它?一个列表保留一个版本变量,该变量会随着每次修改而更改。添加、删除或更改列表中的项会增加版本 创建列表的枚举数时,它将绑定到当时列表的验证。每次调用MoveNext()(或:每次foreach()迭代)时,都会对照原始列表检查此版本。当版本不同时,会引发给

对集合使用
foreach()
将获得一个枚举数并重复调用
MoveNext()

对于数组,我可以在迭代集合时更改集合中的项

但是,在
列表上迭代的代码在第一个循环后抛出异常:

集合已修改;枚举操作可能无法执行

为什么允许数组使用它,而不允许
列表使用它?

一个
列表
保留一个
版本
变量,该变量会随着每次修改而更改。添加、删除或更改列表中的项会增加版本

创建列表的枚举数时,它将绑定到当时列表的验证。每次调用
MoveNext()
(或:每次
foreach()
迭代)时,都会对照原始列表检查此版本。当版本不同时,会引发给定的异常

ArrayEnumerator没有这样的检查,因为数组实际上没有版本字段。但是:

只要集合保持不变,枚举数就保持有效。如果对集合进行了更改(如添加、修改或删除元素),则枚举数将不可恢复地失效,其行为未定义


因此,虽然您的第一个示例似乎有效,但不能保证有效。

在您的第一个循环中,您正在修改
列表,而不是
arr
-您打算这样做吗?
class Program
{
    static void Main()
    {
        int[] arr = new int[5]{ 1,2,3,4,5};
        List<int> list = new List<int>() { 1,2,3,4,5};
        foreach(int i in arr)
        {
            arr[2] = 7;
            Console.WriteLine(i);
        }
        Console.WriteLine();

        foreach (int i in list)
        {
            list[2] = 7;
            Console.WriteLine(i);
        }
        Console.ReadKey();
    }