C# Switch Explained – From Basic To Advanced

by Kenji Elzerman
C# Switch Explained - Kens Learning Curve

If you are known in the development world you might have used the switch statement. Most languages have the switch. It’s a form of checking a decision and acting on it. The C# switch is not any different.

The C# Switch – The Theory

So, how does a C# switch statement work? It first executes an expression. This could be anything; int, bool, return value of a method, etc. Next, a C# switch has cases. Each case represents a value, or result, of the expression. If a case matches the value, the body of the case will be executed. You can use a default case if no cases are hit, but this one is optional.

Pretty simple, right? But then again… Isn’t theory always simple?

A Basic C# Switch

Here is a really basic C# switch:

int number = 4;

switch (number)
{
    case 1:
        Console.WriteLine("You wrote number 1");
        break;
    case 2:
        Console.WriteLine("You wrote number 2");
        break;
    case 3:
        Console.WriteLine("You wrote number 3");
        break;
    case 4:
    case 5:
        Console.WriteLine("You wrote number 4 or 5");
        break;
    default:
        Console.WriteLine($"You wrote something else: {number}");
        break;
}

The switch evaluates the value of the variable number, which is hardcoded 4. Inside the switch you see cases and each case has a possible value of the variable number. Do mind that each case line ends with a ‘:’, not the traditional ‘;’.

Each case has a body, which is a simple Console.WriteLine in my example. A case can end with a keyword break. This means that the C# switch execution has come to an end. If you don’t use break, the next case will be executed, like cases 4 and 5. If the value of the variable number is 4 or 5, you will see You wrote number 4 or 5.

Switch To If

We could transform this C# switch to an If statement with easy:

if (number == 1)
{
    Console.WriteLine("You wrote number 1");
}
else if (number == 2)
{
    Console.WriteLine("You wrote number 2");
}
else if (number == 3)
{
    Console.WriteLine("You wrote number 3");
}
else if (number == 4 || number == 5)
{
    Console.WriteLine("You wrote number 4 or 5");
}
else
{
    Console.WriteLine($"You wrote something else: {number}");
}

This piece of code will give you the same result as the switch.

Switch vs If

If and switch are both decision-making statements, so that’s a similarity. However, when you need to make decisions both will work for you. There is not a real difference in speed, although some claim the C# switch to be faster.

But there is a bit of a difference between if-statements and switch-statements in C#. If the number of conditions is large, the C# compiler creates a HashTable object, which is faster in looking up information. Instead of a C# switch, you can also use a HashTable object. If statements are not changed after compiling; it stays an if statement. This means that if your If statement becomes really big, you should switch to a C# switch.

In the end, it comes down to the way a programmer works. It’s a personal decision or a decision by the team. But I will tell you this: If the C# switch or If statement has big code bodies, switch to the strategy pattern.

The Expression C# Switch

Since the release of C# 7, the C# switch has been a bit changed. You can still use the above style, but you can make it shorter with a pattern. In this case, you use a C# switch expression, which returns the result and stores it in a variable.

var result = number switch
{
    1 => "You wrote number 1",
    2 => "You wrote number 2",
    3 => "You wrote number 3",
    4 or 5 => "You wrote number 4 or 5",
    _ => $"You wrote something else: {number}",
};
Console.WriteLine(result);

Instead of cases you now have expressions. On the left side you see the value of what the variable number could be and on the right side the result, which is returned. When number is 4 or 5; You can use the keyword or if a value should be one or the other.

This way of coding is ideal if the results of the cases, or expressions, are small, like a string. If you want to execute more than one line of code, create methods and execute those from the result of the expression. Keep this style of C# switch small and clean.

Math With C# Switch

We can expand the expression C# switch with something else. Take a look at the following code:

(int numberOne, int numberTwo, string numberOperator) = (10, 5, "+");

int result = numberOperator switch
{
    "+" => numberOne + numberTwo,
    "-" => numberOne - numberTwo,
    _ => numberOne * numberTwo,
};
Console.WriteLine(result);

This C# switch will evaluate a ValueTuple. You check the numberOperator, a variable in the 3rd place of the tuple, and generate an outcome. This is the result:

Result operation switch with operator - C# Switch Explained - Kens Learning Curve

Non-Exhaustive C# Switch

One of the coolest features I recently discovered is this non-exhaustive C# switch. The switch works like an expression C# switch but with extra checks.

Preparation

Now, for this to demonstrate I need some extra code. I create a class Product and an enum Status:

public class Product
{
    public int Id { get; set; }
    public string Title { get; set; }
    public int Stock { get; set; }
    public Status Status { get; set; }
    public bool Available { get; set; }
    public string Image { get; set; }
}

public enum Status
{
    Ordered = 0,
    Delivered = 1,
    Delayed = 2,
    Unknown = 3
}

Next, I create some products:

List<Product> products = new()
{
    new() { Id = 1, Title = "7Up", Status = Status.Ordered, Stock = 10, Available = true },
    new() { Id = 2, Title = "Chips", Status = Status.Ordered, Stock = 0, Available = true },
    new() { Id = 3, Title = "Sugar", Status = Status.Delivered, Stock = 67, Available = true },
    new() { Id = 4, Title = "Meatballs", Status = Status.Delivered, Stock = 5, Available = true },
    new() { Id = 5, Title = "Milk", Status = Status.Delivered, Stock = 7, Available = true },
    new() { Id = 6, Title = "Chewinggum", Status = Status.Delivered, Stock = 0, Available = false },
    new() { Id = 7, Title = "Toiletpaper", Status = Status.Delivered, Stock = 1, Available = true },
    new() { Id = 8, Title = "Tea", Status = Status.Delivered, Stock = 5, Available = true },
    new() { Id = 9, Title = "Coffee", Status = Status.Delivered, Stock = 85, Available = true },
    new() { Id = 10, Title = "Biscuits", Status = Status.Delivered, Stock = 12, Available = true },
    new() { Id = 11, Title = "Chocolate", Status = Status.Delivered, Stock = 89, Available = true },
    new() { Id = 12, Title = "Bread", Status = Status.Delivered, Stock = 167, Available = true },
};

I don’t think this needs a lot of explanation.

Implementing

Time to implement the case guards. What I want to achieve: I want to know if a product needs to be ordered or if there are enough items in stock. I will show you the code first and explain it afterward.

Product product = products[3];

var result = product switch
{
    { Stock: 0 } => $"Product {aMovie.Title} should be ordered.",
    { Stock: var stock, Status: Status.Unknown } when stock < 10 => $"Product {aMovie.Title} is almost out of stock. There are {stock} items left",
    { Stock: var stock } when stock > 10 => $"Product {aMovie.Title} has enough items in stock",
};

I start the expression switch as shown before. But then comes the ‘magic’. I can use the properties of a product inside the expression. The first ‘case’ will be hit when the stock of the selected product is zero.

When the stock is less than 10 and the status is unknown the second case will be hit. The when keyword is a powerful keyword that can help you determine the outcome of the result. Note that I declared the property Stock into the local variable stock.

The third and last case does the same as the second, but will only be hit if the stock is larger than 10, whatever the status is.

Failed to match its input

When you run the code as I have shown you, you will get an error:

Error Non-exhaustive switch - C# Switch Explained - Kens Learning Curve

Non-exhaustive switch expression failed to match its input. What does that even mean? It means that there is no match. None of the cases are hit (…they could have made the message a bit more clear if you ask me).

In the case of product index number 3, the Stock is 5 and the Status is Delivered. I don’t handle that one. I should have added a default case:

Product product = products[3];

string result = product switch
{
    { Stock: 0 } => $"Product {product.Title} should be ordered.",
    { Stock: var stock, Status: Status.Unknown } when stock < 10 => $"Product {product.Title} is almost out of stock. There are {stock} items left",
    { Stock: var stock } when stock > 10 => $"Product {product.Title} has enough items in stock",
    _ => $"No match for {product.Title}",
};

Conclusion On C# Switch

The C# switch is pretty simple, but it has changed a lot after the last updates of C#. It has way more functionality and it’s easier to use. But if I am being honest; I never use a C# switch that much. Mainly because I try to keep my code clean and slim by using other techniques.

Still, the non-exhaustive C# switch is something I love to use because it gives me more control over the outcome of the C# switch.

Test Your Knowledge

[klccampaign id=784860f0-6507-48e0-ab53-5aca15aec85f]

Related Articles

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.

Table Of Contents
Kens Learning Curve