Удаление ImageList - PullRequest
       17

Удаление ImageList

4 голосов
/ 01 марта 2012

Как правильно расположить объект 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;
    }
}

Я уверен, что есть некоторые потенциальные проблемы с этим кодом, поэтому не могли бы вы помочь мне исправить его.

Ответы [ 2 ]

4 голосов
/ 07 марта 2012

Да, он делает копию. Обратите внимание на вызов 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);
}
1 голос
/ 01 марта 2012

ImageList не имеет ссылки на исходное изображение. Когда вы добавляете изображение, ImageList копирует его. Вы можете распоряжаться оригиналом по своему усмотрению.
Однако вам следует вызвать imageList.Images.Clear(); в вашем Dispose ().

...