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