Empty Function Body

ID

csharp.empty_function_body

Severity

info

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

CSharp

Tags

dead-code, reliability

Description

Reports a method whose body is an empty { } block (or a block containing only comments). An empty method silently does nothing while looking like a real implementation; callers cannot tell that the operation was a no-op.

Several shapes where the empty body is required, not accidental, are exempt: override methods and virtual Template-Method hooks (the member cannot be omitted, or exists precisely so a derived class can override it selectively), a same-file interface implementation, a Dispose()/DisposeAsync() on a class that already implements IDisposable/IAsyncDisposable, and Razor Pages convention handlers (OnGet on a PageModel, required for routing). Units carrying a generated-code marker (// <auto-generated> header, the legacy Visual Studio designer header, or [GeneratedCode]) are skipped entirely.

Rationale

A method with an empty body is almost always a sign of an incomplete change: a stub left after a refactoring, a callback that was never wired up, or a method that should have been deleted. Comments do not count as statements — a body that contains only // TODO is still empty and still misleading.

abstract, partial and extern methods are excluded because the language either forbids a body or expects the implementation to be supplied elsewhere.

public class Service
{
    public void Start()        // OK — body has statements
    {
        Initialize();
    }

    public void Stop()         // FLAW — body is empty
    {
    }

    public void Reset()
    {                          // FLAW — only a comment, not a statement
        // TODO: implement
    }

    public abstract void Tick();   // OK — abstract method has no body

    protected virtual void Configure() { }   // OK — virtual Template-Method hook
}

public interface IWorker { void Run(); }

public class NoOpWorker : IWorker
{
    public void Run() { }          // OK — same-file interface implementation
}

Remediation

Decide whether the method should do something, be removed, or be declared abstract to make the "no default behavior" explicit. If a deliberate no-op is required — a virtual hook with nothing to do by default, an interface member that has to exist, a Null Object Dispose() — leaving the body empty is the correct implementation and the rule already recognizes it; document the intent with a comment only if the reason is not obvious from the shape alone.

References