Как правильно реализовать шаблон dispose с помощью метода close (CA1063)
Вопрос
В Руководстве по проектированию фреймворка (2-е изд., стр. 327) говорится:
РАССМОТРИТЕ возможность предоставления метода
Close()
, в дополнение кDispose()
, если близко - это стандартная терминология в данной области.При этом важно, чтобы вы сделали близкую реализацию идентичной
Dispose
и рассмотреть возможность внедренияIDisposable.Dispose
метод в явном виде.
Итак, следуя приведенному примеру, у меня есть этот класс:
public class SomeClass : IDisposable {
private SomeDisposable someInnerDisposable;
public void Open() {
this.someInnerDisposable = new SomeDisposable();
}
void IDisposable.Dispose() {
this.Close();
}
public void Close() {
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing) {
if (disposing) {
this.someInnerDisposable.Dispose();
this.someInnerDisposable = null;
}
}
}
Похоже, FxCop это не нравится:
СА1816 :Майкрософт.Использование :'SomeClass.Close()' вызывает 'GC.SuppressFinalize(object)', метод, который обычно вызывается только в рамках реализации 'IDisposable.Dispose'.Обратитесь к шаблону IDisposable для получения дополнительной информации.
СА1816 :Майкрософт.Использование :Измените 'SomeClass.IDisposable.Dispose()' на вызов 'GC.SuppressFinalize(object)'.Это предотвратит ненужную доработку объекта после того, как он будет удален и выйдет за пределы области видимости.
СА1063 :Майкрософт.Дизайн :Изменить 'SomeClass.IDisposable.Dispose()' так что он вызывает Dispose(true), затем вызывает GC.SuppressFinalize для текущего экземпляра объекта ('this' или 'Me' в Visual Basic), а затем возвращает.
СА1063 :Майкрософт.Дизайн :Переименуйте 'SomeClass.IDisposable.Dispose()' в 'Dispose' и убедитесь, что он объявлен общедоступным и запечатан.
- Как мне правильно реализовать шаблон dispose с помощью метода close?
-или-
- Как мне подавить предупреждения?
Я пытался
[SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly",
Justification = "Framework Design Guidelines say it's ok.")]
void IDisposable.Dispose()
{
this.Close();
}
но FxCop 1.36 все еще сообщает о них.
Редактировать:Изменение его, как было предложено, устраняет все, кроме этого предупреждения:
СА1063 :Майкрософт.Дизайн :Переименуйте 'SomeClass.IDisposable.Dispose()' в 'Dispose' и убедитесь, что он объявлен общедоступным и запечатан.
ПРАВКА 2:CODE_ANALYSIS действительно отсутствовал.Спасибо.
Решение
Измените это по-другому.
Попросите Close() вызвать это.Dispose() и поместите логику в метод Dispose() вместо метода Close().
------------------- Дополнительная информация после редактирования ---------------
Кроме того, изменение объявления на:
public void Dispose()
следует избавиться от другой ошибки.Поскольку вы объявили его как:
void IDisposable.Dispose()
Он не помечен как общедоступный и запечатанный, и FxCop жалуется.Лично я предпочитаю избегать ошибок вместо того, чтобы подавлять их.
Другие советы
Как мне подавить предупреждения?
Функция SuppressMessage() работает только тогда, когда вы указываете флаг CODE_ANALYSIS в качестве символа условной компиляции.