switch statement
Photo by Javier Allegue Barros on Unsplash

Microsoft introduced a more concise and readable syntax for switch expression in C# 8.0, enhancing code clarity and efficiency. In this post, I’d like to compare the new expression syntax to the traditional version and discuss what sets them apart.

Why The New Syntax is Called Switch Expression?

The name “switch expression” shows that the new switch is meant to give a result directly, instead of doing multiple steps. This makes it fit better with functional programming principles and helps create shorter and clearer code.


Pros of the new syntax:

  • Makes code look cleaner and simpler to understand
  • The compiler warns about missing cases
  • Supports complex and expressive matching

Cons of the new syntax:

  • In some cases, it may not be suitable if you need to perform multiple actions


Syntax differences

First, let’s take a look at the syntax difference and move from there. input is the variable that we are doing the switch operation on. a and b are our possible matches and the rest are simply the syntax for the switch

Old syntax:

switch(input) 
{
  case a:
    // code block
    break;
  case b:
    // code block
    break;
  default:
    //  default code block
}

New syntax:

var result = input switch
{
    a => // code block,
    b => // code block,
    _ => // default code block
};

Now, let’s see the difference between them using an example. Following is a function that will return what a letter grade means in English.

We have an enum holding the letter grades with the name of LetterGrade

public enum LetterGrade
{
    A,
    B,
    C,
    D,
    F
}

This is the traditional switch statement example of how you would code the logic:

public static string GetGradeMeaning(LetterGrade grade)
{
    string meaning;
    switch (grade)
    {
        case LetterGrade.A:
            meaning = "Excellent";
            break;
        case LetterGrade.B:
            meaning = "Good";
            break;
        case LetterGrade.C:
            meaning = "Average";
            break;
        case LetterGrade.D:
            meaning = "Below Average";
            break;
        case LetterGrade.F:
            meaning = "Failing";
            break;
        default:
            throw new ArgumentException("Invalid letter grade");
    }
    return meaning;
}

Another version of the traditional switch statement which is more comparable with the new syntax:

public static string GetGradeMeaning(LetterGrade grade)
{
    switch (grade)
    {
        case LetterGrade.A:
            return "Excellent";
        case LetterGrade.B:
            return "Good";
        case LetterGrade.C:
            return "Average";
        case LetterGrade.D:
            return "Below Average";
        case LetterGrade.F:
            return "Failing";
        default:
            throw new ArgumentException("Invalid letter grade");
    }
}

Now, the new switch:

public static string GetGradeMeaning(LetterGrade grade)
{
    return grade switch
    {
        LetterGrade.A => "Excellent",
        LetterGrade.B => "Good",
        LetterGrade.C => "Average",
        LetterGrade.D => "Below Average",
        LetterGrade.F => "Failing",
        _ => throw new ArgumentException("Invalid letter grade")
    };
}

When Should I Use the Traditional Switch Statement?

When you have multiple complex logics that should happen in each case block, it’s easier to use the traditional syntax instead of overcomplicating your code and trying to use the switch expression syntax.

An example where the traditional syntax would be easier to work with:

public static void ProcessStudentDocument(DocumentType docType, string filePath)
{
    switch (docType)
    {
        case DocumentType.Text:
            // Load text file
            string textContent = File.ReadAllText(filePath);
            // Perform some text processing
            int wordCount = textContent.Split(' ').Length;
            // Log the result
            Console.WriteLine($"Word count: {wordCount}");
            break;

        case DocumentType.Image:
            // Load image file
            using var image = Image.FromFile(filePath);
            // Perform some image processing
            using var resizedImage = new Bitmap(image, new Size(100, 100));
            // Save the resized image
            resizedImage.Save("resized_image.jpg");
            break;

        case DocumentType.Video:
            // Load video file
            var video = new Video(filePath);
            // Perform some video processing
            for (int i = 0; i < video.FrameCount; i++)
            {
               // Do Something
            }
            break;

        default:
            throw new ArgumentException("Invalid document type");
    }
}