首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >集合,同时遍历枚举数。

集合,同时遍历枚举数。
EN

Stack Overflow用户
提问于 2017-01-10 10:21:54
回答 2查看 95关注 0票数 2

运行此代码时:

代码语言:javascript
复制
var list = new List<string>
{
    "foo",
    "bar",
};

foreach (var l in list)
{
    Console.WriteLine(l);

    list.Add("bar");
}

引发异常:

System.InvalidOperationException:集合已被修改;枚举操作可能不会执行。

.NET如何知道集合是在枚举器迭代该集合时被修改的?集合对象中是否有此标志?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-10 10:28:49

List<T>内部将其“版本”保存在整数变量中。对列表的每次修改(添加、删除、排序、清除、.)将此版本增加一个。

现在,List<T>的枚举数在初始化时保存此版本号。对于每个MoveNext(),即每次迭代,它都检查列表的版本号是否仍然等于保存的版本号。

这样,它就可以检测列表何时在两次迭代之间被修改。注意,这个实现会导致一个带有整数溢出的特殊错误:Why this code throws 'Collection was modified', but when I iterate something before it, it doesn't?

Sort(Comparison<T> comparison)似乎也有一个bug,它不会增加版本号。此代码:

代码语言:javascript
复制
var list = new List<string>
{
    "foo",
    "bar",
};

foreach (var l in list)
{
    Console.WriteLine(l);
    list.Sort((x, y) => x.CompareTo(y));
}

指纹:

代码语言:javascript
复制
foo
foo
票数 7
EN

Stack Overflow用户

发布于 2017-01-10 10:27:19

是的,典型的解决方案是一个标志、版本值等,例如在List<T>的情况下。

https://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,cf7f4095e4de7646

这是一个版本

代码语言:javascript
复制
 private int _version;

例如。

代码语言:javascript
复制
 public bool MoveNext() {
   ...
   return MoveNextRare()
 } 

 private bool MoveNextRare()
 {                
   if (version != list._version) {
     ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
 }
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41566484

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档