5

ImageListオブジェクトを破棄する適切な方法は何ですか?

private ImageList imageListメンバーを持つクラスがあるとします。さて、ある時点で次のコードを実行します。

// Basically, lazy initialization.
if (imageList == null)
{
    imageList = new ImageList();
    Image[] images = Provider.CreateImages(...);
    foreach (var image in images)
    {
        // Does the 'ImageList' perform implicit copying here
        // or does it aggregate a reference?
        imageList.Images.Add(image); 

        // Do I need to do this?
        //image.Dispose();
    }
}

return imageList;

同じクラスにDispose、次の方法で実行されるメソッドの実装があります。

public void Dispose()
{
    if (!disposed)
    {
        // Is this enough?
        if (imageList != null)
            imageList.Dispose();

        disposed = true;
    }
}

このコードにはいくつかの潜在的な問題があると確信しているので、修正するのを手伝ってください。

4

2 に答える 2

5

はい、コピーします。以下のCreateBitMap呼び出しに注意してください。したがって、リソースの使用をできるだけ少なくするために、廃棄ラインのコメントを解除する必要があります。

 private int Add(ImageList.Original original, ImageList.ImageCollection.ImageInfo imageInfo)
  {
    if (original == null || original.image == null)
      throw new ArgumentNullException("value");
    int num = -1;
    if (original.image is Bitmap)
    {
      if (this.owner.originals != null)
        num = this.owner.originals.Add((object) original);
      if (this.owner.HandleCreated)
      {
        bool ownsBitmap = false;
        Bitmap bitmap = this.owner.CreateBitmap(original, out ownsBitmap);
        num = this.owner.AddToHandle(original, bitmap);
        if (ownsBitmap)
          bitmap.Dispose();
      }
    }
    else
    {
      if (!(original.image is Icon))
        throw new ArgumentException(System.Windows.Forms.SR.GetString("ImageListBitmap"));
      if (this.owner.originals != null)
        num = this.owner.originals.Add((object) original);
      if (this.owner.HandleCreated)
        num = this.owner.AddIconToHandle(original, (Icon) original.image);
    }
    if ((original.options & ImageList.OriginalOptions.ImageStrip) != ImageList.OriginalOptions.Default)
    {
      for (int index = 0; index < original.nImages; ++index)
        this.imageInfoCollection.Add((object) new ImageList.ImageCollection.ImageInfo());
    }
    else
    {
      if (imageInfo == null)
        imageInfo = new ImageList.ImageCollection.ImageInfo();
      this.imageInfoCollection.Add((object) imageInfo);
    }
    if (!this.owner.inAddRange)
      this.owner.OnChangeHandle(new EventArgs());
    return num;
  }

ImageListを破棄すると、すべての画像のコピーが破棄されます。繰り返しになりますが、はい、フォームが閉じたときにそのまま破棄することは、他の破棄行のコメントを解除することに加えて、正しいことです。

protected override void Dispose(bool disposing)
{
  if (disposing)
  {
    if (this.originals != null)
    {
      foreach (ImageList.Original original in (IEnumerable) this.originals)
      {
        if ((original.options & ImageList.OriginalOptions.OwnsImage) != ImageList.OriginalOptions.Default)
          ((IDisposable) original.image).Dispose();
      }
    }
    this.DestroyHandle();
  }
  base.Dispose(disposing);
}
于 2012-03-06T23:52:31.193 に答える
1

ImageList は、元のイメージへの参照を所有していません。画像を追加すると、ImageList によってコピーされます。原本はご都合に合わせて自由に処分してください。
ただしimageList.Images.Clear();、Dispose() を呼び出す必要があります。

于 2012-03-01T12:08:30.263 に答える