Реализация IDisposable на подклассе, когда родитель также реализует IDisposable

Если вы используете Sublime Text на Windows или Mac для редактирования ваших скриптов:

Нажмите View > Line Endings > Unix и снова сохраните файл.

enter image description here [/g0]

25
задан Tanzelax 22 March 2010 в 22:50
поделиться

4 ответа

Когда я просто переопределяю вызов Dispose (bool Disposing), мне кажется очень странным заявить, что я реализую IDisposable без явной функции Dispose () (просто использую унаследованную), но имея все остальное.

Это то, о чем вам не стоит беспокоиться.

Когда вы создаете подкласс класса IDisposable, вся связка «Шаблон удаления» уже обрабатывается за вас базовым классом. Вам действительно не следует ничего делать, кроме как переопределить метод Dispose (bool) , защищенный , и отслеживать, были ли вы уже удалены (чтобы правильно вызвать ObjectDisposedException ).

Подробнее см. мое сообщение в блоге о Создание подклассов от класса IDisposable .


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

26
ответ дан 28 November 2019 в 21:30
поделиться

Зачем усложнять ситуацию, когда вам это не нужно?

Поскольку вы не инкапсулируете какие-либо неуправляемые ресурсы, вам не нужно все это придираться к финализации. И ваши классы являются внутренними, что говорит о том, что вы управляете иерархией наследования в вашей собственной сборке.

Таким образом, простой подход будет следующим:

internal class FooBase : IDisposable 
{ 
  Socket baseSocket; 

  private void SendNormalShutdown() 
  { 
    // ...
  } 

  private bool _disposed = false; 

  public virtual void Dispose() 
  { 
    if (!_disposed)
    { 
      SendNormalShutdown(); 
      baseSocket.Close(); 
      _disposed = true;
    } 
  } 
} 

internal class Foo : FooBase
{ 
  Socket extraSocket; 

  private bool _disposed = false; 

  public override void Dispose()
  { 
    if (!_disposed)
    { 
      extraSocket.Close(); 
      _disposed = true;
    } 

    base.Dispose(); 
  } 
} 

Даже если у вас есть неуправляемые ресурсы, я бы сказал, что вам гораздо лучше заключить их в капсулу в их собственном одноразовом класс и использование их, как если бы вы использовали любой другой одноразовый; так же просто, как и код выше.

5
ответ дан Luke Puplett 28 November 2019 в 21:30
поделиться

Дочерний класс должен переопределить виртуальный Dispose, выполнить любое удаление, специфичное для подкласса, и вызвать суперкласс «Dispose», который, в свою очередь, выполнит свою собственную работу.

РЕДАКТИРОВАТЬ: http://davybrion.com/blog/2008/06/disposing-of-the-idisposable-implementation/ - шаблон, которому я следую в таких случаях. В частности, не класс «Одноразовые», а наследование и переопределения.

1
ответ дан Grant Palin 28 November 2019 в 21:30
поделиться

Идея этого шаблона заключается в том, что вы переопределяете виртуальный метод Dispose , вызывая при необходимости base.Dispose . Базовый класс позаботится обо всем остальном, вызывая виртуальный метод Dispose (и, следовательно, правильную реализацию). Подкласс не должен также реализовывать IDisposable (это IDisposable через наследование)

3
ответ дан 28 November 2019 в 21:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: