Нужно ли реализовывать удаление или финализацию в моих объектах? - PullRequest
4 голосов
/ 18 августа 2010

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

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

Теперь, когда я думаю об этом, я не совсем понимаю, что на самом деле делает функция «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?
}

Ответы [ 3 ]

4 голосов
/ 18 августа 2010

Относительно вашего class Student

Нужно ли мне Dispose()?

Предполагается, что класс Picture IDSposable: Да .Потому что объект 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 гарантированно будет собран в одном прогоне.Финализатор (деструктор) будет бессмысленным, но все же дорогим.

3 голосов
/ 18 августа 2010

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

  • если ваш объект не содержит каких-либо объектов IDisposable или неуправляемых ресурсов (например, подключение к БД), вам вообще не нужно реализовывать IDisposable или финализатор
  • если ваш объект содержит ссылки на объекты IDisposable, тогда вызовите Dispose () для этих объектов в методе Dispose
  • если ваш объект не содержит никаких неуправляемых ресурсов, то не реализует финализатор, сборщик мусора не будет пытаться завершить ваш объект (с падением производительности), если вы не внедрили финализатор.
  • если ваш объект содержит неуправляемые ресурсы, очистите их в финализаторе без перезаписи какого-либо кода очистки в методе Dispose (bool).
1 голос
/ 18 августа 2010

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

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

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

...