Switch Expressions In C# 8

Getting Setup With C# 8

If you aren’t sure if you are using C# 8, or you know you aren’t and want to know how to access these features. Read this quick guide on getting setup with .NET Core and C# 8. On top of that, you will need atleast .NET Core 3.0 Preview 2 – The preview is important! And then also, atleast for me, I had issues with Visual Studio going crazy and not accepting Switch Expressions but VS Code was OK. Again, this is almost like early access so if you don’t want to deal with the pain now, wait until .NET Core 3.0 and C# 8 is officially released!

Existing Switch Statements

So just in case we aren’t sure what existing Switch statements look like, let’s grab some super basic dummy code. Let’s say I have a Bank class that has a status. And based on this status I want to work out if I can walk into the bank or not.

class Bank
{
    public BankBranchStatus Status {get;set;}
}

enum BankBranchStatus
{
    Open, 
    Closed, 
    VIPCustomersOnly
}

So I might have a super simple method like so that returns if I can or can’t walk in :

static bool CheckIfCanWalkIntoBankSwitch(Bank bank, bool isVip)
{
    bool result = false;

    switch(bank.Status)
    {
        case BankBranchStatus.Open : 
            result = true;
            break;
        
        case BankBranchStatus.Closed : 
            result = false;
            break;
        
        case BankBranchStatus.VIPCustomersOnly : 
            result = isVip;
            break;
    }

    return result;
}

Now I know this is a super obtuse example but I want to point out a couple of things.

I know that in my example, I’m returning the result anyway, but let’s pretend I want to use the value. Mind you, even if I wanted to I can’t do something like result = switch(bank.Status) to set the result. You’ll also notice just how much cruft there is in this example. Each line needs an almost redundant case and break statement even though it’s just doing one thing each.

Switch Expressions

Again I have to stress that this is only for C# 8 and above! But let’s rewrite this as a switch statement :

static bool CheckIfCanWalkIntoBank(Bank bank, bool isVip)
{
    var result = bank.Status switch
    {
        BankBranchStatus.Open => true, 
        BankBranchStatus.Closed => false, 
        BankBranchStatus.VIPCustomersOnly => isVip
    };

    return result;
}

What the… So straight away look how succinct this is. We can assign the result of our switch statement directly to our variable, and we do away with all of that case/break junk. Pretty nice. Heck we can even rewrite it a bit to return immediately :

static bool CheckIfCanWalkIntoBank(Bank bank, bool isVip)
{
    return bank.Status switch
    {
        BankBranchStatus.Open => true, 
        BankBranchStatus.Closed => false, 
        BankBranchStatus.VIPCustomersOnly => isVip
    };
}

Hell if we really wanted to, we could get rid of some curlys as well :

static bool CheckIfCanWalkIntoBank(Bank bank, bool isVip) => bank.Status switch
{
    BankBranchStatus.Open => true, 
    BankBranchStatus.Closed => false, 
    BankBranchStatus.VIPCustomersOnly => isVip
};

I’ve been kinda critical with some C# features lately. Namely Default Interface Implementations, but.. This just makes sense!

Extending This Further

Finally, I want to just riff a little bit and show you even more of what the switch expression can do and/or look like. Some of these are actually existing features in C# to do with pattern matching, but I thought I would throw them in here because while you’re here, you may as well get them all out of the way incase you haven’t seen them yet. Now some of my examples again will seem a bit overkill, but coming up with specific examples to show all of these is actually pretty hard!

You can use a when  statement to further your switch statement. For example :

static bool CheckIfCanWalkIntoBank(Bank bank, bool isVip)
{
    return bank.Status switch
    {
        BankBranchStatus.Open => true, 
        BankBranchStatus.Closed => false, 
        BankBranchStatus.VIPCustomersOnly when isVip => true, 
        BankBranchStatus.VIPCustomersOnly when !isVip => false
    };
}

But you can also now do something called Tuple Patterns which means passing more than one parameters to the switch statement.

static bool CheckIfCanWalkIntoBank(Bank bank, bool isVip)
{
    return (bank.Status, isVip) switch
    {
        (BankBranchStatus.Open, _) => true, 
        (BankBranchStatus.Closed, _) => false, 
        (BankBranchStatus.VIPCustomersOnly, true) => true, 
        (BankBranchStatus.VIPCustomersOnly, false) => false
    };
}

Note that you can use the under score (_) character to signify that it should match anything. In this case because it doesn’t matter whether they are a VIP, if the bank is closed it’s closed, then whatever that value is just match it.

And finally, you actually can now pass objects to a switch statement and inspect their properties!

static bool CheckIfCanWalkIntoBank(Bank bank, bool isVip)
{
    return bank switch
    {
        { Status : BankBranchStatus.Open}  => true, 
        { Status : BankBranchStatus.Closed } => false, 
        { Status : BankBranchStatus.VIPCustomersOnly }  => isVip
    };
}

This is so that instead of creating a Tuple from your properties, you just pass in the single object and you can have multiple matching statements separated by a comma. It’s really awesome stuff!

Leave a Comment