The Evolution of the Switch Statement (C#8)

February 02, 2019

Most languages have a version of the switch statement as far as I’m aware; I must admit, I don’t remember one from Spectrum Basic, but ever since then, I don’t think I’ve come across a language that doesn’t have one. The switch statement in C was interesting. For example, the following was totally valid:

[code lang=“c”] switch (value) { case 1: printf(“hello ”); case 2: printf(“world”);
}




If you gave it a value of 1 would print "hello world".  When C# came out, they insisted on using breaks at the end of case statements, or having no code (admittedly there were a few bugs in C caused by accidentally leaving break statements out):



``` csharp


            int value = 1;
            switch (value)
            {
                case 1:
                    Console.Write("hello ");
                    break;
                case 2:
                    Console.Write("world");
                    break;
            }


Anyway, fast forward around 17 years to C# 7.x, and it basically has the same switch statement; in fact, as far as I’m aware, you could write this switch statement in C# 1.1 and it would compile fine. There’s nothing wrong with it, so I imagine MS were thinking why fix it if it’s not broken.

There are limitations, however; for example, what if I want to return the string, like this:




            int value = 1;
            string greeting = string.Empty;
            switch (value)
            {
                case 1:
                    greeting = "hello ";
                    break;
                case 2:
                    greeting = "world";
                    break;
            }

            Console.WriteLine(greeting);


Now it looks a bit cumbersome. What if we could write it like this:



            int value = 1;
            string greeting = value switch
            {
                1 => "hello ",
                2 => "world",
                \_ => string.Empty
            };

            Console.WriteLine(greeting);

From C# 8, you can do just that. The switch statement will return its value. The case syntax is disposed of, and there’s no need for a break statement (which, to be fair, can encourage people to write large swathes of code inside the switch statement - if you don’t believe me then have a look in the Asp.Net Core source!).

And that’s not all. Pattern matching has also been brought in; for example, take the following simple class structure:



    interface IAnimal
    {
        void Eat();
        void Sleep();            
        string Name { get;}
    }

    class Dog : IAnimal
    {
        public string Name { get => "Fido"; }

        public void Eat()
        {
            Console.WriteLine("Dog Eats");
        }

        public void Sleep()
        {
            Console.WriteLine("Dog Sleeps");
        }
    }

    class Cat : IAnimal
    {
        public string Name { get => "Lemmy"; }

        public void Eat()
        {
            Console.WriteLine("Cat Eats");
        }

        public void Sleep()
        {
            Console.WriteLine("Cat Sleeps");
        }
    }


We can put that into a switch statement like this:



            IAnimal animal = new Cat();
            string greeting = animal switch
            {
                Dog d => $"hello dog {d.Name}",
                Cat c => $"hello cat {c.Name}",                
                \_ => string.Empty
            };

            Console.WriteLine(greeting);


We can actually do better that this (obviously better is a relative term). Let’s say that we wanted to do something specific for our particular cat:



            IAnimal animal = new Cat();
            string greeting = animal switch
            {
                Dog d => $"hello dog {d.Name}",
                Cat c when c.Name == "Lemmy" => $"Hello motorcat!",
                Cat c => $"hello cat {c.Name}",                
                \_ => string.Empty
            };

            Console.WriteLine(greeting);

It’s a bit of a silly and contrived example, but it does illustrate the point; further, if you switch the case statements around for the general and specific form of Cat, you’ll get a compile error!



Profile picture

A blog about one man's journey through code… and some pictures of the Peak District
Twitter

© Paul Michaels 2024