CA1821: Remove empty finalizers

Note

This article applies to Visual Studio 2015. If you're looking for the latest Visual Studio documentation, use the version selector at the top left. We recommend upgrading to Visual Studio 2019. Download it here

TypeName RemoveEmptyFinalizers
CheckId CA1821
Category Microsoft.Performance
Breaking Change Non-breaking

Cause

A type implements a finalizer that is empty, calls only the base type finalizer, or calls only conditionally emitted methods.

Rule Description

Whenever you can, avoid finalizers because of the additional performance overhead that is involved in tracking object lifetime. The garbage collector will run the finalizer before it collects the object. This means that two collections will be required to collect the object. An empty finalizer incurs this added overhead without any benefit.

How to Fix Violations

Remove the empty finalizer. If a finalizer is required for debugging, enclose the whole finalizer in #if DEBUG / #endif directives.

When to Suppress Warnings

Do not suppress a message from this rule. Failure to suppress finalization decreases performance and provides no benefits.

Example

The following example shows an empty finalizer that should be removed, a finalizer that should be enclosed in #if DEBUG / #endif directives, and a finalizer that uses the #if DEBUG / #endif directives correctly.

using System.Diagnostics;

public class Class1
{
    // Violation occurs because the finalizer is empty.
    ~Class1()
    {
    }
}

public class Class2
{
    // Violation occurs because Debug.Fail is a conditional method.
    // The finalizer will contain code only if the DEBUG directive
    // symbol is present at compile time. When the DEBUG
    // directive is not present, the finalizer will still exist, but
    // it will be empty.
    ~Class2()
    {
        Debug.Fail("Finalizer called!");
    }
}

public class Class3
{
    #if DEBUG
        // Violation will not occur because the finalizer will exist and
        // contain code when the DEBUG directive is present. When the
        // DEBUG directive is not present, the finalizer will not exist,
        // and therefore not be empty.
        ~Class3()
        {
            Debug.Fail("Finalizer called!");
        }
    #endif
}