The Evolution of the Switch Statement and C# 8
In this article, we take a quick walk through the history fo the switch statement, beginning with C and going up to the latest versions of C#.
Join the DZone community and get the full member experience.
Join For Free
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:
switch (value)
{
case 1:
printf("hello ");
case 2:
printf("world");
}
If you gave it a value of 1, it 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):
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 was 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!
Published at DZone with permission of Paul Michaels, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
Why You Should Consider Using React Router V6: An Overview of Changes
-
Harnessing the Power of Integration Testing
-
Guide To Selecting the Right GitOps Tool - Argo CD or Flux CD
-
Batch Request Processing With API Gateway
Comments