C#idiomatic C#
ca2216fundamentals/code-analysis/quality-rules

Code analysis

CA2216: Disposable types should declare finalizer

Learn about code analysis rule CA2216: Disposable types should declare finalizer

CA2216 Usage enabled by default in .NET 10: No
Fix is breaking or non-breaking Non-breakingApplicable languages C# and Visual Basic

Cause

A type that implements System.IDisposable, and has fields that suggest the use of unmanaged resources, does not implement a finalizer as described by System.Object.Finalize.

Rule description

A violation of this rule is reported if the disposable type contains fields of the following types:

How to fix violations

To fix a violation of this rule, implement a finalizer that calls your System.IDisposable.Dispose method.

When to suppress warnings

It is safe to suppress a warning from this rule if the type does not implement System.IDisposable for the purpose of releasing unmanaged resources.

Suppress a warning

If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.

csharp
#pragma warning disable CA2216
// The code that's violating the rule is on this line.
#pragma warning restore CA2216

To disable the rule for a file, folder, or project, set its severity to none in the configuration file.

ini
[*.{cs,vb}]
dotnet_diagnostic.CA2216.severity = none

For more information, see How to suppress code analysis warnings.

Example

The following example shows a type that violates this rule.

sample · csharpdocs/fundamentals/code-analysis/quality-rules/snippets/csharp/all-rules/ca2216.cssnippet1

csharp
using System;
using System.Runtime.InteropServices;

namespace ca2216
{
    //<snippet1>
    public class DisposeMissingFinalize : IDisposable
    {
        private bool disposed = false;
        private IntPtr unmanagedResource;

        [DllImport("native.dll")]
        private static extern IntPtr AllocateUnmanagedResource();

        [DllImport("native.dll")]
        private static extern void FreeUnmanagedResource(IntPtr p);

        DisposeMissingFinalize()
        {
            unmanagedResource = AllocateUnmanagedResource();
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                // Dispose of resources held by this instance.
                FreeUnmanagedResource(unmanagedResource);
                disposed = true;

                // Suppress finalization of this disposed instance.
                if (disposing)
                {
                    GC.SuppressFinalize(this);
                }
            }
        }

        public void Dispose()
        {
            Dispose(true);
        }

        // Disposable types with unmanaged resources implement a finalizer.
        // Uncomment the following code to satisfy rule:
        //  DisposableTypesShouldDeclareFinalizer
        // ~TypeA()
        // {
        //     Dispose(false);
        // }
    }
    //</snippet1>
}

CA1816: Call GC.SuppressFinalize correctly

See also