.NET Reflector が無料だった頃、私はそれを使用して .NET フレームワーク コードに息を吹き込みました。.NET 2.0 のほとんどのコレクション (これは現在のバージョンにも当てはまると思います) は、次のメカニズムを使用して、ループ中にコレクションの変更を認識することに気付きました。
public class SomeCollection<T>
{
internal int version = 0;
// code skipped for brevity
public void Add(T item)
{
version++;
// add item logic ...
}
public IEnumerator<T> GetEnumerator()
{
return new SomeCollectionEnumerator<T>(this);
}
}
public class SomeCollectionEnumerator<T> : IEnumerator<T>
{
private SomeCollection<T> collection;
private int version;
public SomeCollectionEnumerator(SomeCollection<T> collection)
{
this.version = collection.version;
this.collection = collection;
}
public bool MoveNext()
{
if (this.version != this.collection.version)
{
// collection was modified while iterated over
throw SomeException(...);
}
// iteration logic here...
}
}
ここで、特定のコレクション インスタンス (.NET フレームワークの組み込みコレクション タイプの 1 つ) をメモリに保持する長時間実行アプリケーション (ダウンタイムを最小限に抑え、安定性と信頼性を確保する必要がある、頻繁に使用される Web サービス) の架空のケースを想像してみてください。それが実行される限り。コレクションは頻繁に変更されるため、int.MaxValue
変更が発生する可能性があります。version++
コレクションのすべての変更メソッドの行がオーバーフロー例外をスローするリスクはありますか (オーバーフロー チェックがグローバルに無効にされていないと仮定します)。
反映されたコードの詳細についての記憶が薄いことは認めざるを得ませんが、操作のunckecked
周りのブロックの使用法は覚えていませんversion++
。これは、.NET の組み込みのコレクション型が、このような長時間実行されるアプリケーション シナリオの目的には適していないということですか? 好奇心から、これが実際に起こり得る現実のシナリオに遭遇した人はいますか?