Как я должен наследовать IDisposable?

Baregrep ( Baretail хорош также)

22
задан Andy West 2 December 2009 в 16:52
поделиться

5 ответов

Если есть разумная вероятность того, что абстрактный объект (интерфейс или абстрактный класс) может быть одноразовым , он должен это реализовать. Поток , например, сам не требует IDisposable , равно как и IEnumerator ...

Абстрактная база class может быть проще, так как вы можете иметь стандартную (пустую) реализацию Dispose () тогда и, возможно, шаблон финализатора / Dispose (bool), то есть

void IDisposable.Dispose() { Dispose(true); GC.SuppressFinalize(this); }
protected virtual void Dispose(bool disposing) {}
~BaseType() {Dispose(false);}
20
ответ дан 29 November 2019 в 05:21
поделиться

Если вы знаете, что некоторые реализации ISomeInterface требуют удаления, тогда интерфейс должен наследовать IDisposable, даже если конкретные реализации интерфейса не имеют ничего, что нужно было бы удалить.

Например, в BCL, IDataReader реализует IDisposable, хотя можно, конечно, представить себе реализации считывателя данных, у которых нет внешних ресурсов, которые необходимо удалить.

3
ответ дан 29 November 2019 в 05:21
поделиться

Это зависит от вашего интерфейса, но я бы предпочел №2. Если у вас есть две реализации ISomeInterface и только одна требует удаления, то есть вероятность, что вам потребуется провести рефакторинг.

Обычно, когда вы привязываетесь к интерфейсу, лучше, чтобы этот интерфейс наследовал IDisposable , а не базовый класс; если ваш интерфейс не наследует IDisposable , вы должны преобразовать его в IDisposable , чтобы избавиться от объекта, и это создает риск InvalidCast ...

2
ответ дан 29 November 2019 в 05:21
поделиться

Если вы хотите, чтобы весь ваш код имел дело с ISomeInterfaces в целом, то да, все они должны быть одноразовыми.

Если нет, то код, который создает FirstClass, должен его удалить:

using (FirstClass foo = new FirstClass()) {
    someObjectThatWantsISomeInterface.Act(foo);
}

в противном случае вы всегда можете использовать что-то вроде этот метод расширения:

public static void DisposeIfPossible(this object o) {
    IDisposable disp = o as IDisposable;
    if (disp != null)
        disp.Dispose();
}

// ...
someObject.DisposeIfPossible(); // extension method on object

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

2
ответ дан 29 November 2019 в 05:21
поделиться

Мой совет - переходите к корню, а не напрямую к конкретному классу. Пункт 2 относится к корню, и вы руководствуетесь каким-то контрактом с FirstClass. Если вы знаете, что классы должны реализовывать какой-то интерфейс, тогда вы хотите убедиться, что интерфейс, который они подписывают в контракте, iwth наследует IDisposable

1
ответ дан 29 November 2019 в 05:21
поделиться
Другие вопросы по тегам:

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