繁体   English   中英

为什么从 ConditionalWeakTable 中删除键时 IEnumerator.MoveNext 不抛出?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM