gpt4 book ai didi

c# - 为什么从 ConditionalWeakTable 中删除键时 IEnumerator.MoveNext 不抛出异常?

转载 作者:行者123 更新时间:2023-12-05 03:34:24 24 4
gpt4 key购买 nike

下面的代码不会抛出,即使在枚举过程中修改了枚举集合。

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]

这是故意的还是偶然的?如果是前者,那么在 key 被垃圾收集的情况下,什么会阻止抛出异常?

非常感谢!

最佳答案

按设计。

引自 the docs .

The returned enumerator does not extend the lifetime of any object pairs in the table, other than the current one. It does not return entries that have already been collected or that were added after the enumerator was retrieved. Additionally, it may not return all entries that were present when the enumerator was retrieved, for example, entries that were collected or removed after the enumerator was retrieved but before they were enumerated.

枚举器的 Current 属性指向的对象不会被垃圾回收,可以安全访问。如果可枚举中更远的键被 GC 处理或删除,枚举器将不会访问该元素。

正如 canton7 在评论中提到的,这是 ConditionalWeakTable 保持线程安全所必需的 - 其他线程可能会在另一个线程的枚举期间删除元素。

关于c# - 为什么从 ConditionalWeakTable 中删除键时 IEnumerator.MoveNext 不抛出异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70151906/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com