ディクショナリからキーを列挙するディクショナリに関係する不思議な状況がありますが、ディクショナリには含まれているキーの一部が含まれていません。
Dictionary<uint, float> dict = GetDictionary(); // Gets values, 6268 pairs
foreach(uint key in dict.Keys)
{
if (!dict.ContainsKey(key))
Console.WriteLine("Wat? "+key);
}
上記は、6268 キーのうちの 2 つを表示します。Int32.MaxValue (369099203 と 520093968) より小さい正の値の 2 つのキーについて特別なことは何もありません。
カウントをチェックすると、次のことがわかります。
Console.WriteLine(dict.Count); // 6268
Console.WriteLine(dict.Keys.Count()); // 6268
Console.WriteLine(dict.Keys.Count(dict.Keys.Contains)); // 6266
これは、.NET4.5 CLR で実行されるシングル スレッドの .NET4 コードです。辞書はバニラです。Dictionary<uint, float>
つまり、カスタムの等値比較器はありません。uint/int の違いが原因でハッシュの問題が発生していると思いContainsKey(key)
ますが、ディクショナリの Key コレクションで返されるすべてのキーに対して真であることが保証されるべきではありませんか? 特に、下のコード スニペットのように KeyCollection オブジェクトのみを見ると、合計数と含まれるオブジェクトの数がずれており、奇妙ICollection
な動作のように感じられます。
編集:
予想どおり、合理的な説明があるようです。コレクションは、初期化中に 2 つの同時スレッドによって以前に変更されました。何かが「時々壊れる」場合、それはスレッドの問題であり、確かに。複数のスレッドから dict にアクセスすると、明らかに内部状態が混乱して、残りの存続期間は半機能状態になる可能性がありますが、例外は発生しません。
並行辞書に切り替えて、おそらくこの質問を削除します。ありがとう。