69

How will a C# switch statement's default label handle a nullable enum?

Will the default label catch nulls and any unhandled cases?

Trey Mack
  • 4,215
  • 2
  • 25
  • 31
  • 4
    C# Language Specification, 8.7.2 "The switch statement". http://msdn.microsoft.com/en-us/library/ms228593.aspx – Dennis Feb 19 '13 at 05:44

4 Answers4

109

If it's null, it will hit the default label.

public enum YesNo
{
    Yes,
    No,
}

public class Program
{
    public static void Main(string[] args)
    {
        YesNo? value = null;
        switch (value)
        {
            case YesNo.Yes:
                Console.WriteLine("Yes");
                break;
            case YesNo.No:
                Console.WriteLine("No");
                break;
            default:
                Console.WriteLine("default");
                break;
        }
    }
}

The program will print default.

Unless null is handled.

public class Program
{
    public static void Main(string[] args)
    {
        YesNo? value = null;
        switch (value)
        {
            case YesNo.Yes:
                Console.WriteLine("Yes");
                break;
            case YesNo.No:
                Console.WriteLine("No");
                break;
            case null:
                Console.WriteLine("NULL");
                break;
            default:
                Console.WriteLine("default");
                break;
        }
    }
}

prints NULL.

If you have an unhandled enum value that was added later:

public enum YesNo
{
    Yes,
    No,
    FileNotFound,
}

public class Program
{
    public static void Main(string[] args)
    {
        YesNo? value = YesNo.FileNotFound;
        switch (value)
        {
            case YesNo.Yes:
                Console.WriteLine("Yes");
                break;
            case YesNo.No:
                Console.WriteLine("No");
                break;
            default:
                Console.WriteLine("default");
                break;
        }
    }
}

It still prints default.

Trey Mack
  • 4,215
  • 2
  • 25
  • 31
2

You can have a case for null.

switch (MyNullableEnum)
{
   case Option1:
       break;
   case Option2:
       break;
   case Option3:
       break;
   case null:
       break;
   default:
       break;
}
bahramzy
  • 133
  • 3
  • 14
1

You can use the null-coalescing operator ?? to route null switch values to a specific case label other than default:

public static IEnumerable<String> AsStrings(this IEnumerable<Char[]> src)
{
    Char[] rgch;

    var e = src.GetEnumerator();
    while (e.MoveNext())
    {
        switch ((rgch = e.Current)?.Length ?? -1)
        {
            case -1:    // <-- value when e.Current is 'null'
                yield return null;
                break;
            case 0:
                yield return String.Empty;
                break;
            case 1:
                yield return String.Intern(new String(rgch[0], 1));
                break;
            default:   // 2...n
                yield return new String(rgch);
                break;
        }
    }
}
Glenn Slayden
  • 17,543
  • 3
  • 114
  • 108
-1

It's worth to mention that C# 8.0 introduced a new Property Pattern for a switch expression. Now you can implement default logic to switch by using underscore:

public double Calculate(int left, int right, Operator op) =>
    op switch 
{
    Operator.PLUS => left + right,
    Operator.MINUS => left - right,
    Operator.MULTIPLY => left * right,
    Operator.DIVIDE => left / right,
    _    =>  0 // default
}

Ref. https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8

Przemek Struciński
  • 4,990
  • 1
  • 28
  • 20
  • For this switch expression you *must* add a default branch, it's not optional here. (How else can the compiler make sure the expression always returns a value?) – Hans Kesting Mar 24 '21 at 08:09