Partager via


CA2213: Disposable fields should be disposed

Note

This article applies to Visual Studio 2015. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here

Item Value
TypeName DisposableFieldsShouldBeDisposed
CheckId CA2213
Category Microsoft.Usage
Breaking Change Non Breaking

Cause

A type that implements System.IDisposable declares fields that are of types that also implement IDisposable. The Dispose method of the field is not called by the Dispose method of the declaring type.

Rule Description

A type is responsible for disposing of all its unmanaged resources; this is accomplished by implementing IDisposable. This rule checks to see whether a disposable type T declares a field F that is an instance of a disposable type FT. For each field F, the rule attempts to locate a call to FT.Dispose. The rule searches the methods called by T.Dispose, and one level lower (the methods called by the methods called by FT.Dispose).

How to Fix Violations

To fix a violation of this rule, call Dispose on fields that are of types that implement IDisposable if you are responsible for allocating and releasing the unmanaged resources held by the field.

When to Suppress Warnings

It is safe to suppress a warning from this rule if you are not responsible for releasing the resource held by the field, or if the call to Dispose occurs at a deeper calling level than the rule checks.

Example

The following example shows a type TypeA that implements IDisposable (FT in the previous discussion).

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);
        }
    }
}

Example

The following example shows a type TypeB that violates this rule by declaring a field aFieldOfADisposableType (F in the previous discussion) as a disposable type (TypeA) and not calling Dispose on the field. TypeB corresponds to T in the previous discussion.

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);
      }
   }
}

See Also

System.IDisposable Dispose Pattern