switch expression – mönstermatchningsuttryck med nyckelordet switch
Du använder switch
uttrycket för att utvärdera ett enda uttryck från en lista över kandidatuttryck baserat på en mönstermatchning med ett indatauttryck. Information om instruktionen switch
som stöder switch
-like-semantik i en instruktionskontext finns i instruktionsavsnittet switch
i artikeln Urvalsinstruktioner.
I följande exempel visas ett switch
uttryck som konverterar värden för en enum
som representerar visuella riktningar i en onlinekarta till motsvarande kardinalriktningar:
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
}
}
Föregående exempel visar de grundläggande elementen i ett switch
uttryck:
- Ett uttryck följt av nyckelordet
switch
. I föregående exempel är det metodparameterndirection
. - Uttryckets
switch
armar, avgränsade med kommatecken. Varjeswitch
uttrycksarm innehåller ett mönster, ett valfritt skiftlägesskydd,=>
token och ett uttryck.
I föregående exempel använder ett switch
uttryck följande mönster:
- Ett konstant mönster: för att hantera uppräkningens definierade värden
Direction
. - Ett ignorerande mönster: för att hantera alla heltalsvärden som inte har motsvarande medlem i
Direction
uppräkningen (till exempel(Direction)10
). Det gör uttrycketswitch
uttömmande.
Viktigt!
Information om de mönster som stöds av switch
uttrycket och fler exempel finns i Mönster.
Resultatet av ett switch
uttryck är värdet för uttrycket för den första switch
uttrycksarmen vars mönster matchar indatauttrycket och vars skiftlägesskydd, om det finns, utvärderas till true
. Uttrycksarmarna switch
utvärderas i textordning.
Kompilatorn genererar ett fel när en arm med lägre switch
uttryck inte kan väljas eftersom en arm med högre switch
uttryck matchar alla dess värden.
Skiftlägesskydd
Ett mönster kanske inte är tillräckligt uttrycksfullt för att ange villkoret för utvärderingen av ett armuttryck. I sådana fall kan du använda ett skiftlägesskydd. Ett skiftlägesskydd är ett annat villkor som måste uppfyllas tillsammans med ett matchat mönster. Ett skiftlägesskydd måste vara ett booleskt uttryck. Du anger ett skiftlägesskydd efter nyckelordet when
som följer ett mönster, vilket visas i följande exempel:
public readonly struct Point
{
public Point(int x, int y) => (X, Y) = (x, y);
public int X { get; }
public int Y { get; }
}
static Point Transform(Point point) => point switch
{
{ X: 0, Y: 0 } => new Point(0, 0),
{ X: var x, Y: var y } when x < y => new Point(x + y, y),
{ X: var x, Y: var y } when x > y => new Point(x - y, y),
{ X: var x, Y: var y } => new Point(2 * x, 2 * y),
};
I föregående exempel används egenskapsmönster med kapslade var-mönster.
Icke-uttömmande växeluttryck
Om inget av ett switch
uttrycks mönster matchar ett indatavärde genererar körningen ett undantag. I .NET Core 3.0 och senare versioner är undantaget en System.Runtime.CompilerServices.SwitchExpressionException. I .NET Framework är undantaget en InvalidOperationException. I de flesta fall genererar kompilatorn en varning om ett switch
uttryck inte hanterar alla möjliga indatavärden. Listmönster genererar ingen varning när alla möjliga indata inte hanteras.
Dricks
För att garantera att ett switch
uttryck hanterar alla möjliga indatavärden anger du en switch
uttrycksarm med ett ignorerande mönster.
Språkspecifikation för C#
Mer information finns i switch
avsnittet uttryck i kommentaren om funktionsförslaget.