[英]Why doesn't IEnumerator.MoveNext throw when removing keys from a ConditionalWeakTable?
即使在枚举期间修改了枚举集合,以下代码也不会抛出。
using System;
using System.Collections;
using System.Runtime.CompilerServices;
namespace ConsoleApp1
{
class MyKey
{
}
class Program
{
static void Main(string[] args)
{
ConditionalWeakTable<MyKey, string> table = new();
MyKey k1 = new();
MyKey k2 = new();
MyKey k3 = new();
table.Add(k1, "v1");
table.Add(k2, "v2");
table.Add(k3, "v3");
var enumerator = ((IEnumerable)table).GetEnumerator();
while(enumerator.MoveNext()) // no exception thrown
{
Console.WriteLine(enumerator.Current);
table.Remove(k1);
table.Remove(k2);
table.Remove(k3);
}
}
}
}
[ConsoleApp1.MyKey, v1]
这是故意的,还是偶然的? 如果是前者,那么在密钥被垃圾收集的情况下,什么会阻止抛出异常?
非常感谢!
按设计。
从文档中引用。
返回的枚举数不会延长表中任何 object 对的生命周期,除了当前的。 它不返回已收集或检索枚举器后添加的条目。 此外,它可能不会返回检索枚举器时存在的所有条目,例如,在检索枚举器之后但在枚举之前收集或删除的条目。
枚举器的Current
属性所指向的 object 将不会被垃圾收集并且可以安全地访问。 如果可枚举中的某个键被 GC 或删除,则枚举器将根本无法访问该元素。
正如 canton7 在评论中提到的,这是ConditionalWeakTable
保持线程安全所必需的 - 其他线程可能会在另一个线程的枚举期间删除元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.