Поделиться через


CA2213: следует высвобождать высвобождаемые поля

TypeName

DisposableFieldsShouldBeDisposed

CheckId

CA2213

Категория

Microsoft.Usage

Критическое изменение

Не критическое

Причина

Тип, реализующий интерфейс 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);
      }
   }
}

См. также

Ссылки

IDisposable

Другие ресурсы

Implementing Finalize and Dispose