Мне нужно реализовать удаление или финализацию в моих объектах?

Слишком долго я позволял сборщику мусора творить чудеса, снимая с себя все обязанности.

К сожалению, это так и не превратилось в проблему ... Так что я никогда не задумывался об этом предмете.

Теперь, когда я думаю об этом, я не совсем понимаю, что на самом деле делает функция «dispose» и как и когда ее следует реализовать.

Тот же вопрос по доработке ...

И последний вопрос ... У меня есть класс pictureManipulation: когда мне нужно сохранить / изменить размер / изменить формат ... Я запускаю новый экземпляр этого класса, использую его объекты и ... ну, пусть сборка мусора убивает экземпляр

class student
{
   public void displayStudentPic()
   {
      PictureManipulation pm = new PictureManipulation();
      this.studentPic = pm.loadStudentImage(id); 
   }
}

Class Test
{
  student a = new Student();
  a.displayStudentPic();
  // Now the function execution is ended... does the pm object is dead? Will the GC will kill it?
}

person Asaf    schedule 18.08.2010    source источник
comment
Как правило, вы должны реализовать IDisposable, если какие-либо объекты, которые вы используете, реализуют это. Или если вы используете P / Invoke.   -  person Powerlord    schedule 18.08.2010


Ответы (3)


Что касается вашего class Student

Мне нужен Dispose()?

Предполагая, что класс Picture - IDisposable: Да. Потому что объект Student «владеет» studentPic, и это делает его ответственным за его очистку. Минимальная реализация:

class Student : IDisposable
{
   private PictureClass studentPic;
   public void Dispose()
   {
      if (studentPic != null)
        studentPic.Dispose();
   }
   ...
}

И теперь вы используете объект Student, например:

void Test
{
  using (Student a = new Student())
  {
     a.displayStudentPic();    
  } // auto Dispose by using() 
}

Если вы не можете / не можете использовать using(){} блок, просто вызовите a.Dispose();, когда закончите с ним.

Но обратите внимание, что (намного) лучший дизайн здесь - это избегать хранения объекта изображения внутри вашего объекта Student. Это создает целую цепочку обязанностей.

Нужен ли мне финализатор?

Нет. Поскольку при сборе объекта Student, его объект studentPic гарантированно будет собран в том же прогоне. Финализатор (деструктор) был бы бессмысленным, но все же дорогим.

person Henk Holterman    schedule 18.08.2010
comment
Отличный ответ, который поможет сделать первый шаг к пониманию ... теория очень важна, но я всегда считаю первый шаг самым сложным :) - person Asaf; 19.08.2010

Вам нужно реализовать метод Dispose только в том случае, если ваш тип содержит некоторые неуправляемые ресурсы, такие как подключения к БД, дескрипторы файлов и т. Д., Или если некоторые из объектов, которые удерживаются вашим типом, реализуют интерфейс IDisposable. Вот несколько моментов, которые следует учитывать при реализации стандартного шаблона Dispose:

  • если ваш объект не содержит каких-либо объектов IDisposable или неуправляемых ресурсов (например, подключения к БД), вам вообще не нужно реализовывать IDisposable или финализатор
  • если ваш объект содержит ссылки на объекты IDisposable, вызовите Dispose () для этих объектов в методе Dispose.
  • Если ваш объект не содержит неуправляемых ресурсов, тогда не реализован финализатор, сборщик мусора не будет пытаться завершить ваш объект (который снижает производительность), если вы не реализовали финализатор.
  • если ваш объект содержит неуправляемые ресурсы, очистите их в финализаторе без перезаписи какого-либо кода очистки в методе Dispose (bool).
person theburningmonk    schedule 18.08.2010
comment
+1: @Asaf: Managed Resources = Любой простой старый объект .Net (который вы могли писать или не писать), который не имеет дескриптора файла, базы данных или другого объекта, существующего вне вашей запущенной программы. - person Binary Worrier; 18.08.2010
comment
@Binary: я думаю, что Managed-resource == действительно имеет (косвенный) указатель на что-то. - person Henk Holterman; 18.08.2010
comment
@Henk: Managed Resource = То, о чем беспокоится сборщик мусора. Нет? - person Binary Worrier; 18.08.2010
comment
@Binary, Мое лучшее понимание: Managed-resource == косвенный / вложенный неуправляемый ресурс. Пуля 2 в этом ответе. - person Henk Holterman; 18.08.2010
comment
@Henk: Похоже, я в меньшинстве, похоже, нет окончательного определения управляемого ресурса, но все же, похоже, следует вашему определению. Я исправлюсь, сэр :) - person Binary Worrier; 18.08.2010
comment
+1: Теперь, прочитав ответ Хенка Холтермана и увидев действительно простой пример ... я могу оценить ваши рекомендации. Спасибо Асаф - person Asaf; 19.08.2010

Вам нужно позаботиться об удалении объекта, если он содержит ресурсы, отличные от просто памяти, удерживаемой самим объектом.

Например, если ваш объект абстрагирует файл, вы должны контролировать, когда файл будет выпущен, или вы очень сильно испортите ситуацию: ваше приложение завершило его использование, и оно по-прежнему будет заблокировано, пока GC не избавится от вашего объекта.

Чтобы узнать, как это сделать правильно, прочтите руководства по dispose и finalize, а также предложение using () {}.

person Pavel Radzivilovsky    schedule 18.08.2010