C# Advanced

C# 8 Switch Expressions

C# 8 switch Expressions
Table of Contents

The switch Expressions

C# 8 supports a new interesting feature called switch expressions where the cases are expressions.

By the end of this article, you’ll know:

  • What switch expression is and how to use it
  • How the switch expression works
  • How to use optional elements like property, var, empty property, and null patterns with the switch expression for more specific pattern matching
  • What browser editor you can use that supports C# 8 syntax.

Ready? Here we go!


Let’s look at the syntax improvements for the switch expressions:

  • Instead of switch (variable), the variable comes before the switch keyword. 
  • The patterns are now comma-separated list (,). 
  • The lambda arrow => replaces the case keyword and the colon (:). It is used between the pattern and the expression. 
  • The left side of the => is a pattern with an optional when clause to add additional conditions. The right side of the => is an expression without a return keyword. 
  • The switch expressions do not support break and return keywords.
  • The underscore (_) character replaces the default keyword to signify that it should match anything if reached. 
  • The bodies are now expressions instead of statements. The selected body becomes the switch expression’s result.
  • Only a single expression can be used on the right side of the arrow and the expression value needs to be returned as a result.
C#'s 8 Switch Expressions Syntax

Note: If switch expression reaches the end without a match will throw an exception.


Switch Statements vs C# 8 Switch Expressions Syntax

Traditional switch statements vs C# 8 switch expressions. The syntax of switch expressions is different but looks cleaner and more readable as compared to the old switch statements.

Switch Statements vs Switch Expressions Syntax

Example 1

Let’s look at a very simple example.

C#'s 8 Switch Expressions Example 1

Example 2

1. Let’s start off with creating two new classes called Fruit and Vegetable to illustrate the concept of switch expressions. The code for the classes is as follows.

public class Fruit
{
    public string Name{get; set;}
    public bool InStock{get; set;}
    public int Quantity{get; set;}
    
    public Fruit(string name, bool inStock, int quantity){
        Name = name;
        Quantity = quantity;
        InStock = inStock;
    }
}

public class Vegetable
{
    public string Name{get; set;}
    public bool InStock{get; set;}
    public Vegetable(string name, bool inStock){
        Name = name;
        InStock = inStock;
    }
}

2. Create PrintInfo() method to add switch expressions code.

public static void PrintInfo(object food)
{

}

The food variable is used as an object because object type allows for a variable of any type.

3. In the below example, switch expression uses thetype pattern Fruit item and Vegetable item to check for the Fruit and Vegetable types. If the food object matches any of the declared types, it then uses that type in the body of the selected switch expression.

public static void PrintInfo(object food)
{
	var result = food switch
	{
		Fruit item => $"{item.Name} is a {nameof(Fruit)}. Quantity available {item.Quantity}.",
		Vegetable item => $"{item.Name} is a {nameof(Vegetable)}.",		
		_ => "Food info not found."
	};
	
	Console.WriteLine(result);
}

4.You can use when clause to perform more specific pattern matching on the item variable. Now the type and its value is checked for a match.

public static void PrintInfo(object food)
{
	var result = food switch
	{
		Fruit item when (item.InStock==true) => $"{item.Name} is a {nameof(Fruit)}. Quantity available {item.Quantity}.",
		Vegetable item => $"{item.Name} is a {nameof(Vegetable)}.",		
		_ => "Food info not found."
	};
	
	Console.WriteLine(result);
}

Switch Expressions with Property Pattern

C# 8 allows optional elements with type patterns. The commonly used one is the property pattern by adding curly braces with properties and values for a more specific pattern matching. Let’s rewrite the switch expression to reflect the new changes:

public static void PrintInfo(object food)
{
	var result = food switch
	{
		Fruit {InStock: true} item => $"{item.Name} is a {nameof(Fruit)}. Quantity available {item.Quantity}.",
		Vegetable item => $"{item.Name} is a {nameof(Vegetable)}.",		
		_ => "Food info not found."
	};
	
	Console.WriteLine(result);
}

Using the previous code example, the first case now applies the constant pattern to the InStock property of the item, checking whether it has the value true. Now you can eliminate the when clause in this case.

The item would only be a match if the food is a type Fruit and its InStock property is true to output a different result based on that.


Switch Expressions with var Pattern

Another optional feature of switch expression is the use of a var pattern. In the below example, the second case applies this pattern to the Quantity property.

public static void PrintInfo(object food)
{
	var result = food switch
	{
		Fruit {InStock: true, Quantity: var qty} item => $"{item.Name} is a {nameof(Fruit)}. Quantity available is {qty}.",
		Vegetable item => $"{item.Name} is a {nameof(Vegetable)}.",		
		_ => "Food info not found."
	};
	
	Console.WriteLine(result);
}

The var will always succeed and declare a new variable to hold the value of item.Quantity property. Now you can drop item variable because it is never used in the right side of the expression.

C#'s 8 Switch Expressions with var Pattern

Switch Expressions with Empty Property and null Patterns

You can also check for null values by adding a null case to catch all the nulls. This ensures that the value passed to all the patterns including property patterns is not null. To deal with the non-null objects, use case with { }. Now the completed switch structure is as follows.

public static void PrintInfo(object food)
{
	var result = food switch
	{
		Fruit {InStock: true, Quantity: var qty} item => $"{item.Name} is a {nameof(Fruit)}. Quantity available is {qty}.",
		Vegetable item => $"{item.Name} is a {nameof(Vegetable)}.",		
		{} => food.ToString(),
		null => "null"
	};
	
	Console.WriteLine(result);
}

Output

Apple is a Fruit. Out of Stock.
Peach is a Fruit. Quantity available 12.
Potato is a Vegetable.
Invalid food.


C# 8 Online Editor

You can write your code with any editor, but you’ll be much more productive with an online code editor for instantly testing C# code snippets.

You can use Sharplab.io editor that supports C# 8 to test the above code examples. Copy and paste below code in the editor to see the result. 

using System;

public class Program
{
	public static void Main()
	{
		Fruit f = new Fruit("Apple", false, 0);
        
        //Print Fruit
		PrintInfo(f);
        
        Fruit f1 = new Fruit("Peach", true, 12);
        
        //Print Fruit
		PrintInfo(f1);
        
        Vegetable veg = new Vegetable("Potato", true);
        
        //Print Vegetable
		PrintInfo(veg);
        
        // Null Check
		Fruit f2 = null;
		
		//Print Fruit
		PrintInfo(f2);
        
	}
    
    public static void PrintInfo(object food)
    {
        var result = food switch
        {
            Fruit {InStock: false} item => $"{item.Name} is a {nameof(Fruit).ToLower()}. Out of stock.",
            //Fruit item when (item.InStock==true) => $"{item.Name} is a {nameof(Fruit)}. Quantity available {item.Quantity}.",
                
            //Fruit {InStock: true, Quantity: var qty} item => $"{item.Name} is a {nameof(Fruit)}",
            Fruit {InStock: true, Quantity: var qty} => $"Available quantity of {nameof(Fruit)} is {qty}.",
                
            Vegetable item => $"{item.Name} is a {nameof(Vegetable)}.",
                
            //{} => food.ToString(),
            //null => "null",

            _ => "Food info not found."
        };

        Console.WriteLine(result);
    }
}
	
public class Fruit
{
    public string Name{get;	set;}
    public bool InStock{get; set;}
    public int Quantity{get; set;}
    
    public Fruit(string name, bool inStock, int quantity){
        Name = name;
        Quantity = quantity;
        InStock = inStock;
    }
}

public class Vegetable
{
    public string Name{get;	set;}
    public bool InStock{get; set;}
    public Vegetable(string name, bool inStock){
        Name = name;
        InStock = inStock;
    }
}