No Empty Finalizer

ID

csharp.no_empty_finalizer

Severity

low

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

medium

Resource

Code Smell

Language

CSharp

Tags

code-style, performance

Description

Reports class finalizers (~ClassName()) whose body has no executable statement. Comments alone do not count as statements, so a finalizer that contains only comments is also reported.

Rationale

Declaring a finalizer registers every instance of the class with the runtime’s finalization queue. The GC promotes those instances to a later generation and runs the finalizer thread before they can actually be collected. When the finalizer body is empty this overhead delivers no value — the type pays the full finalization cost for nothing. If the finalizer exists to release unmanaged resources the body must do that work; otherwise the finalizer should be removed entirely so the GC can collect the type on the normal path.

public class Handle
{
    ~Handle()                      // FLAW
    {
    }
}

public class OnlyComments
{
    ~OnlyComments()                // FLAW
    {
        // leave to the GC, nothing to do
    }
}

public class Buffer                // OK, no finalizer at all
{
}

public class NativeHandle
{
    private IntPtr _handle;

    ~NativeHandle()                // OK, releases unmanaged state
    {
        Release(_handle);
    }

    private static void Release(IntPtr h) { }
}

Remediation

Either fill the finalizer with the cleanup it should perform, or delete the finalizer declaration entirely. In the vast majority of cases the right answer is to delete it and rely on IDisposable for deterministic resource release.