3

ImageList は、挿入されたすべての画像のコピーを作成する必要があります。したがって、オリジナルをリストに追加した後、それらを破棄しても安全です。

次のテストケースが失敗するのはなぜですか?

Bitmap test = new Bitmap(128, 128);
ImageList il = new ImageList();

il.Images.Add(test);
Assert.AreEqual(1, il.Images.Count); // OK, image has been inserted
test.Dispose(); // now let's dispose the original
try
{
    var retrievalTest = il.Images[0];
}
catch (ArgumentException) // ... but this Exception happens!
{
}

Assert.AreEqual(1, il.Images.Count); // and this will fail

画像を取得しようとすると、ImageList は元の画像が破棄されていることを発見し、ImageList から削除します。

ImageList はイメージのコピーを作成するはずだと思ったのですが、なぜそうなったのでしょうか。

4

2 に答える 2

6

はい、ImageList はビットマップのコピーを作成します。しかし、テスト コードは、.NET フレームワークで非常に一般的な、有名な遅延初期化パターンに違反しています。重要なのは、コピーをいつ作成するかです。これは、必要な場合にのみ行います。コードに小さな変更を加えて、それを急いでください。

il.Images.Add(test);
var dummy = il.Handle;     // <== NOTE: added
test.Dispose();            // no problem

そして、廃棄がもはや問題ではないことがわかります。

ここで適切なアドバイスをする方法がわかりません。コードが合成的すぎます。これは一般に十分に機能し、消費者がビットマップ、Treeview、または ListView を使用し始めると、ImageList はコピーを作成します。一般に、ImageList をコレクション オブジェクトとして使用することは避けてください。そのように作成されたわけではありません。ビューをモデルから分離すれば、問題を回避できます。

于 2013-07-14T13:13:53.057 に答える