当前位置: 首页 > 知识库问答 >
问题:

遍历枚举器时的集合

何越
2023-03-14

运行此代码时:

var list = new List<string>
{
    "foo",
    "bar",
};

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

    list.Add("bar");
}

引发异常:

系统。无效操作异常:集合被修改;枚举操作可能无法执行。

怎么做。NET知道该集合在枚举器迭代该集合时被修改了吗?集合对象中是否有此标志?

共有2个答案

狄承望
2023-03-14

是的,典型的解决方案是标志、版本值等,例如在<代码>列表的情况下

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

这是个版本

 private int _version;

例如。

 public bool MoveNext() {
   ...
   return MoveNextRare()
 } 

 private bool MoveNextRare()
 {                
   if (version != list._version) {
     ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
 }
太叔英锐
2023-03-14

A<代码>列表

现在是<代码>列表的枚举数

通过这种方式,它可以检测列表在两次迭代之间何时被修改。请注意,此实现会导致一个带有整数溢出的特殊错误:为什么此代码会抛出“Collection was修改”,但当我在它之前迭代某些内容时,它不会?。

关于排序(比较),似乎也有一个bug

var list = new List<string>
{
    "foo",
    "bar",
};

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

打印:

foo
foo
 类似资料:
  • 我有一个简单的枚举,我想迭代一下。为此,我采用了顺序和迭代器协议,如下面的代码所示。顺便说一句,这可以复制/粘贴到Xcode 8中的游乐场。 但是for in循环生成错误消息“Type”节。Type不符合协议“Sequence”。协议一致性在我的扩展中;那么,这个代码有什么问题? 我知道还有其他方法可以做到这一点,但我想知道这种方法有什么问题。 谢谢

  • 问题内容: 我有一个如下的JavaScript对象: 现在我想通过所有回路元素(,,…),并得到他们的键和值。我怎样才能做到这一点? 我可以根据需要修改JavaScript对象。我的最终目标是遍历一些键值对,如果可能的话,我想避免使用。 问题答案: 您可以使用其他人所示的循环。但是,您还必须确保获得的键是对象的实际属性,而不是来自原型。 这是代码段: 用Object.keys()替代: 请注意,使

  • 我的Flutter项目中有一个Dart枚举,如下所示: 如果我有一些随机枚举状态,如,我如何迭代到下一个枚举(而不需要做一些事情,如用开关语句映射它们)? 我在这个,这个和这个的帮助下找到了答案,所以我把它贴在下面。

  • 问题内容: 以下代码不起作用,因为Freemarker似乎将[]中的表达式的值强制转换为String,然后将其用作键,这并不是实际期望的值。 准备模板模型: my.ftl: 在Freemarker文档中,描述了如何访问Enum本身,但是我没有找到有关如何使用Enum作为键从哈希中获取值的任何信息。 谢谢。 问题答案: 要对此释义Freemarker文档常见问题, 您不能在myMap [key]表达

  • 在Java中,有没有办法从现有枚举中定义一个新枚举?我想要以下功能。 1、2、3和所有这些都必须相同,即, 一个真实的例子是天、星期、周末、讲座、派对等。

  • 我需要弄清楚如何使用定义为以下内容的枚举参数列表应用基于注释的筛选: 所以我的如下所示: 我见过很多关于如何对单个枚举值进行条件查询和筛选的问题,但还没有关于对一组枚举值进行筛选的问题。是否有一种方法可以显式地强制转换单个值?