Missing Switch Default

ID

csharp.missing_switch_default

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

CSharp

Tags

control-flow, reliability, switch

Description

Reports switch statements that declare no default section. A switch over an enum is reported too, even when every member declared today has a case label. Only switch expressions (x switch { …​ }) are exempt.

Rationale

A switch without a default section does nothing at all for every value the author did not enumerate. A new protocol code, an unexpected status string or a value that slipped past input validation then flows on silently with the state it had before the switch, and the defect surfaces far from its cause. An explicit default forces a decision: fall back to a documented behaviour, or fail loudly.

This holds for an enum selector too. Covering every member that exists today proves nothing about tomorrow — an enum is extended by adding a member, and a switch that enumerated the old set stops handling the new one without a single compiler warning.

public string Describe(int code)
{
    switch (code)                     // FLAW — nothing happens for any other code
    {
        case 1:
            return "created";
        case 2:
            return "deleted";
    }

    return null;
}

public string Name(Level level)
{
    switch (level)                    // FLAW — Level may gain a member later
    {
        case Level.Low:
            return "low";
        case Level.High:
            return "high";
    }

    return null;
}

public string DescribeSafely(int code)
{
    switch (code)                     // OK — the fallback is explicit
    {
        case 1:
            return "created";
        case 2:
            return "deleted";
        default:
            throw new ArgumentOutOfRangeException(nameof(code));
    }
}

Remediation

Add a default section. Prefer a fallback that cannot be mistaken for success: throw ArgumentOutOfRangeException, log the unexpected value, or return a well-defined "unknown" result. If the enumeration really is complete and a fallback is meaningless, convert the statement into a switch expression so the compiler checks exhaustiveness for you.