Big note: These are switch expressions not switch statements.
Original documentation: switch expression (C# reference)
In depth release notes for the switch expressions feature
(Tweet about scope)[https://twitter.com/MoienTajik/status/1512551734081728515]
Via original documentation
public static class SwitchExample
{
public enum Direction
{
Up,
Down,
Right,
Left
}
public enum Orientation
{
North,
South,
East,
West
}
public static Orientation ToOrientation(Direction direction) => direction switch
{
Direction.Up => Orientation.North,
Direction.Right => Orientation.East,
Direction.Down => Orientation.South,
Direction.Left => Orientation.West,
_ => throw new ArgumentOutOfRangeException(nameof(direction), $"Not expected direction value: {direction}"),
};
public static void Main()
{
var direction = Direction.Right;
Console.WriteLine($"Map view direction is {direction}");
Console.WriteLine($"Cardinal orientation is {ToOrientation(direction)}");
// Output:
// Map view direction is Right
// Cardinal orientation is East
}
}
Note:
- The variable that is evaluated by the
switch
is before the keyword - There is no
case
orbreak
default
is now handled by an underscore_
via the discard pattern
int GetValue(bool a, bool b) => (a, b) switch
{
(false, false) => 0,
(false, true) => 1,
(true, false) => 2,
(true, true) => 3
}
Note:
- Here we flatten multiple
if
statements into a flat truth table - This uses the tuple pattern
var jwtKeyBytes = builder.Configuration["JwtKey"] switch
{
null or "" => RandomNumberGenerator.GetBytes(32),
var value => Convert.FromBase64String(value)
}
Note:
- Think of this as a ternary expression where in C# we would make use of the conditional operator
?:
or in other words, the short one lineif
statement. - While this syntax might look a little different (it did for me at first sight) this is the same as Example 1 where there the
direction
variable was being used in theswitch
and here it isbuilder.Configuration["JwtKey"]
instead
Dictionary<char, int> charValues = new Dictionary<char, int>{
['A'] = 1,
['B'] = 2,
['C'] = 3,
}
int CharValues(char c) => c switch {
'A' => 1,
'B' => 2,
'C' => 3,
}
Note:
- While there are no fancy
switch
things happening, it's the clarity that the new expression gives us where we can replace mapping objects with equally readable and allocationless(!) expressions
Via Andy Gocke Another via David Fowler with two parameters
int Sum(Span<int> s) => switch
{
[] => 0,
[var x, .. var xs] => x + Sum(xs)
}
Note:
- The tweet comments how it's looking more like F# and off the top of my head reading this for the first time, I had no idea what's happening.
- Also, don't do recursion this way, it's just neat looking
Via me
bool isCorrectTable = (firstColumnHeader, secondColumnHeader) switch
{
("Tile", "Original") => true,
_ => false
};
Note:
- This is just to create a variable while using tuples rather than use a Switch Expression as a function
Dictionary<string, string> Parse(string s) =>
s.Split(',')
.Select(s => s.Split('=') switch
{
[var k, var v] => (k, v),
_ (null, null),
})
.Where(p => p.k != null)
.ToDictionary(p => p.k, p => p.v);
Note:
- This is designed to take in a string like
a=b,c=d,e=f
- We get to see a switch expression inside a LINQ
Select()
call
return items switch
{
[var item] => item,
[] => null,
[..] => throw new InvalidOperationException("Multiple")
};
- Doing
GetSingleOrDefault()
without LINQ