Switch expressions were introduced in C# 8. There's plenty of places in codebases, which may be rewritten in this new style.
For example, I have some code, which is used for parsing packets from a stream of bytes:
switch (command)
{
case Command.C1:
return new P1();
case Command.C2:
return new P2();
default:
stream.Position++;
return null;
}
The problem is - it can't be converted to a switch expression like
return command switch
{
Command.C1 => new P1(),
Command.C3 => new P2(),
_ => { stream.Position++; return null; }
};
The first thing that got in my mind was to use a Func<>
, which compiles:
return command switch
{
Command.C1 => new P1(),
Command.C3 => new P2(),
_ => new Func<AbstractPacket>(() => { stream.Position++; return null; })()
};
F# already allows code with multiple statements in each branch:
match command with
| Command.C1 -> Some(P1() :> AbstractPacket)
| Command.C2 -> Some(P2() :> AbstractPacket)
| _ ->
stream.Position <- stream.Position + 1
None
Now I'm stuck using switch-statements, but is there any option to write this as a switch-expression without any weird hacks?
Also, you can write multiple statements in a case without using curly braces { }. As per the above syntax, switch statement contains an expression or literal value. An expression will return a value when evaluated. The switch can includes multiple cases where each case represents a particular value.
The expression used in a switch statement must have an integral or character type, or be of a class type in which the class has a single conversion function to an integral or character type. There can be any number of case statements within a switch.
Control passes to the case statement whose constant-expression value matches the value of expression . The switch statement can include any number of case instances. However, no two constant-expression values within the same switch statement can have the same value.
1) The expression used in switch must be integral type ( int, char and enum). Any other type of expression is not allowed.
Your only supported choice is the func like you did. See [this article][1] for more information. His example:
var result = operation switch
{
"+" => ((Func<int>)(() => {
Log("addition");
return a + b;
}))(),
"-" => ((Func<int>)(() => {
Log("subtraction");
return a - b;
}))(),
"/" => ((Func<int>)(() => {
Log("division");
return a / b;
}))(),
_ => throw new NotSupportedException()
};
Just because switch expressions are new doesn't mean they are the best for all use cases. They are not designed to contain multiple commands.
Edit: I suppose you could also simply call external functions instead of making anonymous ones. [1]: https://alexatnet.com/cs8-switch-statement/
With:
TRes Call<TRes>(Func<TRes> f) => f();
its looks like:
return command switch {
Command.C1 => new P1(),
Command.C3 => new P2(),
_ => Call(() => { stream.Position++; return null; }),
};
or:
var result = operation switch {
"+" => Call(() => {
Log("addition");
return a + b;
}),
"-" => Call(() => {
Log("subtraction");
return a - b;
}),
"/" => Call(() => {
Log("division");
return a / b;
}),
_ => throw new NotSupportedException(),
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With