Следует высвобождать высвобождаемые поля
Обновлен: Ноябрь 2007
TypeName |
DisposableFieldsShouldBeDisposed |
CheckId |
CA2213 |
Категория |
Microsoft.Usage |
Критическое изменение |
Не критическое |
Причина
Тип, реализующий интерфейс System.IDisposable, объявляет поля, принадлежащие типам, которые также реализуют интерфейс IDisposable. Метод Dispose поля не вызывается методом Dispose объявляющего типа.
Описание правила
Тип обеспечивает освобождение всех своих неуправляемых ресурсов за счет реализации интерфейса IDisposable. Данное правило проверяет, объявляет ли освобождаемый тип T поле F, которое является экземпляром освобождаемого типа FT. Для каждого поля F правило пытается найти вызов метода FT.Dispose. Правило выполняет поиск методов, вызываемых методом T.Dispose, и методов следующего уровня (то есть методов, вызываемых методами, вызываемыми методом FT.Dispose).
Предотвращение нарушений
Если в коде выполняется выделение и освобождение неуправляемых ресурсов, содержащихся в поле, то, чтобы устранить нарушение данного правила, вызовите метод Dispose для полей, принадлежащих типам, реализующим интерфейс IDisposable.
Отключение предупреждений
Отключение предупреждений о нарушении данного правила безопасно в том случае, если в коде не требуется выполнять освобождение ресурсов, содержащихся в полях, или вызов метода Dispose осуществляется на более глубоком уровне дерева вызовов, чем тот, на котором выполняется проверка.
Пример
В следующем примере показан тип TypeA, который реализует интерфейс IDisposable (FT в предыдущем описании).
using System;
namespace UsageLibrary
{
public class TypeA :IDisposable
{
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// Dispose managed resources
}
// Free native resources
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Disposable types implement a finalizer.
~TypeA()
{
Dispose(false);
}
}
}
В следующем примере показан тип TypeB, который нарушает данное правило: он объявляет поле aFieldOfADisposableType (F в предыдущем описании) в качестве освобождаемого типа (TypeA) и не вызывает метод Dispose для этого поля. Тип TypeB соответствует типу T в предыдущем описании.
using System;
namespace UsageLibrary
{
public class TypeB : IDisposable
{
// Assume this type has some unmanaged resources.
TypeA aFieldOfADisposableType = new TypeA();
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
// Dispose of resources held by this instance.
// Violates rule: DisposableFieldsShouldBeDisposed.
// Should call aFieldOfADisposableType.Dispose();
disposed = true;
// Suppress finalization of this disposed instance.
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}
public void Dispose()
{
if (!disposed)
{
// Dispose of resources held by this instance.
Dispose(true);
}
}
// Disposable types implement a finalizer.
~TypeB()
{
Dispose(false);
}
}
}
См. также
Ссылки
Реализация методов Finalize и Dispose для очистки неуправляемых ресурсов