9

In C# 8, switch expressions were introduced. What happens if a switch expression is not exhaustive? In other words, what happens if I don't test for every possible value?

static void Main(string[] args)
{
    int x = 1;
    int imExhaustive = x switch
    {
        3 => 4,
        _ => 0   // x = 1 matches this
    };
    int okFine = x switch
    {
        1 => 4   // x = 1 matches this
    };
    int noMatch = x switch
    {
        3 => 4   // No match
    };
}
Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Josh
  • 2,958
  • 3
  • 16
  • 27

4 Answers4

10

If the switch expression is not exhaustive, the compiler produces a warning. At runtime, if you pass a value that is not handled, a SwitchExpressionException is thrown.

This is documented in the speclet for new patterns feature in C# 8.0: https://github.com/dotnet/csharplang/blob/master/proposals/csharp-8.0/patterns.md#switch-expression

The compiler shall produce a warning if it proves (using those techniques) that some possible input value might not match some switch_expression_arm at runtime.

At runtime, the result of the switch_expression is the value of the expression of the first switch_expression_arm for which the expression on the left-hand-side of the switch_expression matches the switch_expression_arm's pattern, and for which the case_guard of the switch_expression_arm, if present, evaluates to true.

If there is no such switch_expression_arm, the switch_expression throws an instance of the exception System.Runtime.CompilerServices.SwitchExpressionException.

Julien Couvreur
  • 4,473
  • 1
  • 30
  • 40
1

Depends.

If there's a match: It matches, and everything is fine.

If there's no match: A SwitchExpressionException is thrown.

Best practice seems to be to write exhaustive switch expressions. If you don't, and nothing explodes, you might just be getting lucky.

The compiler will warn you if your switch expression is not exhaustive, but it's not an error and it'll compile and run anyway.

(Just ran into this, so thought I'd share - It's nowhere in the documentation yet, though C# 8 is still in Preview)

Josh
  • 2,958
  • 3
  • 16
  • 27
1

In order to remove this warning, add a default expression.

   exception switch
    {
        ValidationException vExp => new ValidationErrorDetail
        {
            
        },
        ApiException apiExp => new ApiErrorDetail
        {
           
        },
        ProcessException pExp => new ErrorDetail
        {
           
        },
        _ => new ErrorDetail
        {

        }
    };

Add _ => and Default Expression to be excuted.

Aamir
  • 95
  • 1
  • 10
0

For the case of unnamed enum values, I consider C#'s behavior of throwing an exception correct and desirable. So I disable the warning in my .editorconfig:

[*.cs]
dotnet_diagnostic.CS8524.severity = none # The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value.
Frank Schwieterman
  • 24,142
  • 15
  • 92
  • 130