Обычно отказ от вызова Dispose указывает на возможную ошибку или небрежный код и может привести к трудностям для поиска ошибок. В идеале я хотел бы заметить, не вызывается ли Disposed во время модульных тестов.
Один из методов, который мы использовали, заключался в том, чтобы поместить Debug.Assert в Finalizer.
#if DEBUG
~MyClass()
{
Debug.Assert(false, “MyClass.Dispose() was not called”);
}
#endif
И мы обнаружили, что щелкаем по окнам сообщений assert, но это не работало с сборками непрерывной интеграции, которые игнорировали всплывающие окна.
3 ответа
Если вы каким-то образом регистрируете это вместо использования Debug.Assert и используете инъекцию зависимостей, чтобы указать реализацию вашего регистратора, вы можете использовать имитационное тестирование, чтобы поймать это. Итак, ваш класс может принять экземпляр регистратора в своем конструкторе или предоставить экземпляр по умолчанию, а затем вести себя следующим образом:
public MyClass : IDisposable
{
IEventLogger _eventLogger;
public MyClass() : this(EventLogger.CreateDefaultInstance())
{
}
public MyClass(IEventLogger eventLogger)
{
_eventLogger = eventLogger;
}
// IDisposable stuff...
#if DEBUG
~MyClass()
{
_eventLogger.LogError("MyClass.Dispose() was not called");
}
#endif
}
Для обнаружения этой проблемы можно написать правило fxCop.
Кроме того, проверка того, что все виды использования IDisposable используются внутри блока using {}, значительно упрощает решение этой проблемы.
Правило, которое я проверил, для ручных вызовов Dispose () или использования using {}
Ручные вызовы для удаления, конечно, труднее обнаружить во всех ситуациях, поскольку могут существовать управление потоком или исключения, которые могут препятствовать возникновению вызова.
Вы можете использовать объектную структуру Mock (например, RhinoMocks), чтобы убедиться, что вызывается IDisposable.Dispose (). Если Dispose () не был вызван, фреймворк автоматически завершит сборку.
Похожие вопросы
Новые вопросы
c#
C # (произносится как «резкий») - это высокоуровневый, статически типизированный язык программирования с несколькими парадигмами, разработанный Microsoft. Код C # обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, включая, среди прочего, .NET Framework, .NET Core и Xamarin. Используйте этот тег для вопросов о коде, написанном на C # или в формальной спецификации C #.