Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 集合被修改为异常。它在引擎盖下是如何工作的?_C# - Fatal编程技术网

C# 集合被修改为异常。它在引擎盖下是如何工作的?

C# 集合被修改为异常。它在引擎盖下是如何工作的?,c#,C#,若在枚举期间修改集合,列表将产生此异常,但它是如何工作的?列表是否在每次启动枚举时都在内部设置一些标志,然后在修改集合的每个方法中检查它?如果您多次枚举同一个列表会怎么样?它如何跟踪其状态 下面是一个基本示例: using System; using System.Linq; public class Program { public static void Main() { var collection = Enumerable.Range(0, 100).T

若在枚举期间修改集合,列表将产生此异常,但它是如何工作的?列表是否在每次启动枚举时都在内部设置一些标志,然后在修改集合的每个方法中检查它?如果您多次枚举同一个列表会怎么样?它如何跟踪其状态

下面是一个基本示例:

using System;
using System.Linq;

public class Program
{
    public static void Main()
    {
        var collection = Enumerable.Range(0, 100).ToList();
        foreach(var item in collection)
        {
            Console.WriteLine(item);
            collection.RemoveAt(0); // how does list knows that we are enumerating collection?
        }
    }
}
我很想用谷歌搜索答案,但快速搜索是没有用的。据我记忆所及,C#不是开源的,所以我无法检查源代码。反射是一种选择,但我宁愿将其保存为最后手段。

列表类包含一个名为
\u version
的私有字段。它是一个整数,每次添加、删除、排序或反转列表时都会递增

开始枚举列表时,
list
生成一个枚举器实例,该实例立即获取
\u version
字段的副本,并将其存储在自己的名为
version
的成员变量中。每次从枚举器请求项目时,它都会进行检查以确保
version==\u version
。如果基础列表已更改,则其版本将更改;当检测到这种情况时,枚举器抛出您看到的异常


请参阅以查看实现。

“据我所知,C#不是开源的”一个简单的web搜索将为您解答这个问题,从而避免记住它。下面是一个链接,回答您的问题:(您正在查找
\u version
字段)不确定您需要知道的原因。信息隐藏原理告诉我们,不必知道设计决策是一件好事。您需要知道的是,在列表更改后使用枚举数会导致异常。依赖任何更具体的东西都是不好的做法,因为将来可能会发生变化。@ThomasHilbert这不是一般的枚举行为,而是
列表的枚举器(以及其他特定的枚举实现)的行为。@ThomasHilbert知道和依赖是有区别的。你越了解事物的工作原理,你就越能更好地使用它。