Это будет действительный базовый класс для IDisposable
IDisposable шаблон дорог в реализации. Я насчитал 17 строк кода, прежде чем даже начал фактически распоряжаться ресурсами.
Эрик Липперт недавно написал сообщение в блоге, в котором затронул интересный момент: каждый раз, когда запускается финализатор, это ошибка. Я думаю, что это имеет смысл. Если шаблон IDisposable всегда используется, Finalizer всегда должен подавляться. У него никогда не будет шанса бежать. Если мы признаем, что запуск финализатора является ошибкой, имеет ли смысл иметь руководство, которое заставит разработчиков наследовать следующий абстрактный класс и запретить непосредственную реализацию интерфейса IDisposable.
public abstract class AbstractDisaposableBase: IDisposable
{
~AbstractDisaposableBase()
{
ReportObjectLeak();
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected abstract void Dispose(bool disposing);
[Conditional("DEBUG")]
private void ReportObjectLeak()
{
//Debug.Assert(false, "leaked instance");
//throw new Exception("leaked instance");
}
}
Преимущества очевидны:
- Реализация утилизации становится простой и безошибочной, как показано ниже:
class MyClass1 : DisablableBase
{
protected override void Dispose(bool disposing)
{
//dispose both managed and unmamaged resources as though disposing==true
}
}
Не найден объект, о котором сообщили
Одноразовый узор всегда соблюдается
Но есть ли проблемы с таким руководством?
Одна из возможных проблем заключается в том, что для всех одноразовых объектов будет определен финализатор. Но так как финализатор всегда подавляется, не должно быть никаких штрафов за производительность.
о чем ты думаешь?
2 ответа
Имеет ли смысл иметь руководство, чтобы заставить разработчиков выводить из следующего абстрактного класса
Нет, исключительно по той причине, что C# не имеет множественного наследования. Интерфейсы описывают поведение, наследование диктует "is-a". Вы строго ограничите объектно-ориентированный дизайн ваших классов, если будете применять это правило.
Например, вы не можете ввести базовые классы для бизнес-объектов, которые не являются одноразовыми, где бы был производный класс.
Но так как финализатор всегда подавляется, не должно быть никаких штрафов за производительность.
Экземпляры AbstractDisaposableBase
подклассы по-прежнему будут участвовать в управлении очередью финализации, поэтому это повлияет на производительность.