MusterabgleichPattern Matching

Muster testen, ob ein Wert eine bestimmte Form hat, und können Informationen vom Wert extrahieren, wenn er die entsprechende Form hat.Patterns test that a value has a certain shape, and can extract information from the value when it has the matching shape. Der Musterabgleich stellt eine kürzere Syntax für Algorithmen bereit, die Sie bereits verwenden.Pattern matching provides more concise syntax for algorithms you already use today. Sie erstellen bereits mithilfe vorhandener Syntax Musterabgleichalgorithmen.You already create pattern matching algorithms using existing syntax. Sie schreiben if- oder switch-Anweisungen, die Werte testen.You write if or switch statements that test values. Wenn diese Anweisungen anschließend übereinstimmen, extrahieren und verwenden Sie die Informationen von diesem Wert.Then, when those statements match, you extract and use information from that value. Die neuen Syntaxelemente sind Erweiterungen für Anweisungen, mit denen Sie bereits vertraut sind: is und switch.The new syntax elements are extensions to statements you are already familiar with: is and switch. Diese neuen Erweiterungen kombinieren das Testen von Werten mit dem Extrahieren dieser Information.These new extensions combine testing a value and extracting that information.

In diesem Thema wird die neue Syntax betrachtet, um Ihnen zu zeigen, wie dadurch ein lesbarer, kurzer Code ermöglicht wird.In this topic, we'll look at the new syntax to show you how it enables readable, concise code. Ein Musterabgleich ermöglicht Idiome, bei denen Daten und der Code getrennt sind, im Gegensatz zu objektorientierten Entwürfen, bei denen Daten und die Methoden, die sie bearbeiten, eng gekoppelt sind.Pattern matching enables idioms where data and the code are separated, unlike object oriented designs where data and the methods that manipulate them are tightly coupled.

Wir arbeiten mit Strukturen, die geometrische Formen mithilfe Musterabgleichanweisungen darstellen, um diese neuen Idiome zu veranschaulichen.To illustrate these new idioms, let's work with structures that represent geometric shapes using pattern matching statements. Sie sind wahrscheinlich mit dem Erstellen von Klassenhierarchien und dem Erstellen virtueller und überschriebener Methoden vertraut, um Objektverhalten anhand des Laufzeittyps des Objekts anzupassen.You are probably familiar with building class hierarchies and creating virtual methods and overridden methods to customize object behavior based on the runtime type of the object.

Diese Techniken sind nicht für Daten geeignet, die nicht in einer Klassenhierarchie strukturiert sind.Those techniques aren't possible for data that isn't structured in a class hierarchy. Wenn Daten und Methoden getrennt sind, benötigen Sie andere Tools.When data and methods are separate, you need other tools. Die neuen Musterabgleichkonstrukte ermöglichen eine saubere Syntax, um Daten zu untersuchen und anhand jeder Bedingung dieser Daten Steuerungsflüsse zu bearbeiten.The new pattern matching constructs enable cleaner syntax to examine data and manipulate control flow based on any condition of that data. Sie schreiben bereits if-Anweisungen und switch, die den Wert einer Variable testen.You already write if statements and switch that test a variable's value. Sie schreiben is-Anweisungen, die einen Typ einer Variable testen.You write is statements that test a variable's type. Musterabgleich fügt neue Funktionen zu diesen Anweisungen hinzu.Pattern matching adds new capabilities to those statements.

In diesem Thema erstellen Sie eine Methode, die den Bereich der verschiedenen geometrischen Formen berechnet.In this topic, you'll build a method that computes the area of different geometric shapes. Aber Sie tun dies, ohne auf objektorientierte Techniken zurückzugreifen und eine Klassenhierarchie für die verschiedenen Formen zu erstellen.But, you'll do it without resorting to object oriented techniques and building a class hierarchy for the different shapes. Sie verwenden stattdessen Musterabgleich.You'll use pattern matching instead. Sie machen jede Form zu einem struct anstatt zu einer Klasse, um weiter hervorzuheben, dass wir keine Vererbung verwenden.To further emphasize that we're not using inheritance, you'll make each shape a struct instead of a class. Beachten Sie, dass unterschiedliche struct-Typen keinen normalen benutzerdefinierten Basistyp angeben können, sodass Vererbung kein möglicher Entwurf ist.Note that different struct types cannot specify a common user defined base type, so inheritance is not a possible design. Während Sie dieses Beispiel bearbeiten, vergleichen Sie diesen Code damit, wie er als Objekthierarchie strukturiert wäre.As you go through this sample, contrast this code with how it would be structured as an object hierarchy. Wenn die Klasse, die Sie abfragen und bearbeiten müssen, keine Klassenhierarchie ist, ermöglicht Musterabgleich sehr elegante Entwürfe.When the data you must query and manipulate is not a class hierarchy, pattern matching enables very elegant designs.

Anstatt mit einer Definition einer abstrakten Form zu starten und verschiedene bestimmte Formklassen hinzuzufügen, beginnen wir mit einfachen reinen Datendefinitionen für jede der geometrischen Formen:Rather than starting with an abstract shape definition and adding different specific shape classes, let's start instead with simple data only definitions for each of the geometric shapes:

public class Square
{
    public double Side { get; }

    public Square(double side)
    {
        Side = side;
    }
}
public class Circle
{
    public double Radius { get; }

    public Circle(double radius)
    {
        Radius = radius;
    }
}
public struct Rectangle
{
    public double Length { get; }
    public double Height { get; }

    public Rectangle(double length, double height)
    {
        Length = length;
        Height = height;
    }
}

public struct Triangle
{
    public double Base { get; }
    public double Height { get; }

    public Triangle(double @base, double height)
    {
        Base = @base;
        Height = height;
    }
}

Wir schreiben von diesen Strukturen eine Methode, die den Bereich einiger Formen berechnet.From these structures, let's write a method that computes the area of some shape.

Der Musterausdruck des is-TypsThe is type pattern expression

Vor C# 7 mussten Sie jeden Typ in einer Reihe von if- und is-Anweisungen testen:Before C# 7, you'd need to test each type in a series of if and is statements:

public static double ComputeArea(object shape)
{
    if (shape is Square)
    {
        var s = shape as Square;
        return s.Side * s.Side;
    } else if (shape is Circle)
    {
        var c = shape as Circle;
        return c.Radius * c.Radius * Math.PI;
    }
    // elided
    throw new ArgumentException(
        message: "shape is not a recognized shape",
        paramName: nameof(shape));
}

Der oben dargestellte Code ist ein klassischer Ausdruck des Typmusters: Sie testen eine Variable, um ihren Typ zu bestimmen, und handeln anhand dieses Typs unterschiedlich.That code above is a classic expression of the type pattern: You're testing a variable to determine its type and taking a different action based on that type.

Dieser Code wird einfacher, indem Sie Erweiterungen für den is-Ausdruck verwenden, um eine Variable zuzuweisen, wenn der Test erfolgreich ausgeführt wird:This code becomes simpler using extensions to the is expression to assign a variable if the test succeeds:

public static double ComputeAreaModernIs(object shape)
{
    if (shape is Square s)
        return s.Side * s.Side;
    else if (shape is Circle c)
        return c.Radius * c.Radius * Math.PI;
    else if (shape is Rectangle r)
        return r.Height * r.Length;
    // elided
    throw new ArgumentException(
        message: "shape is not a recognized shape",
        paramName: nameof(shape));
}

In dieser aktualisierten Version testet der is-Ausdruck die Variable und weist sie einer neuen Variablen des richtigen Typs zu.In this updated version, the is expression both tests the variable and assigns it to a new variable of the proper type. Beachten Sie ebenfalls, dass die Version den Rectangle-Typ enthält, der ein struct ist.Also, notice that this version includes the Rectangle type, which is a struct. Der neue is-Ausdruck funktioniert mit Werttypen sowie mit Verweistypen.The new is expression works with value types as well as reference types.

Sprachregeln für Musterabgleichausdrücke helfen Ihnen, das Ergebnis eines Musterausdrucks nicht falsch zu verwenden.Language rules for pattern matching expressions help you avoid misusing the results of a match expression. Im obigen Beispiel sind die Variablen s, c und r nur im Geltungsbereich und werden definitiv zugewiesen, wenn die entsprechenden Musterabgleichausdrücke true-Ergebnisse haben.In the example above, the variables s, c, and r are only in scope and definitely assigned when the respective pattern match expressions have true results. Wenn Sie versuchen, eine der Variablen an einem anderen Ort zu verwenden, erzeugt Ihr Code Compilerfehler.If you try to use either variable in another location, your code generates compiler errors.

Betrachten wir beide dieser Regeln im Detail, beginnend mit dem Geltungsbereich.Let's examine both of those rules in detail, beginning with scope. Die Variable c ist im Geltungsbereich nur im else-Zweig der ersten if-Anweisung.The variable c is in scope only in the else branch of the first if statement. Die Variable s liegt im Geltungsbereich in der Methode ComputeArea.The variable s is in scope in the method ComputeArea. Jeder Zweig einer if-Anweisung bildet nämlich einen separaten Geltungsbereich für Variablen.That's because each branch of an if statement establishes a separate scope for variables. Die eigentliche if-Anweisung macht dies jedoch nicht.However, the if statement itself does not. Das bedeutet, dass Variablen, die in der if-Anweisung deklariert wurden, im gleichen Geltungsbereich der if-Anweisung sind (in diesem Fall die Methode). Dieses Verhalten ist nicht spezifisch für den Musterabgleich, entspricht jedoch dem definierten Verhalten für variable Geltungsbereiche sowie für if- und else-Anweisungen.That means variables declared in the if statement are in the same scope as the if statement (the method in this case.) This behavior is not specific to pattern matching, but is the defined behavior for variable scopes and if and else statements.

Die Variablen c und s werden zugewiesen, wenn die jeweiligen if-Anweisungen aufgrund des definitiv zugewiesenen „when true“-Mechanismus „true“ sind.The variables c and s are assigned when the respective if statements are true because of the definitely assigned when true mechanism.

Tipp

Die Beispiele in diesem Thema verwenden die empfohlenen Konstrukte, bei denen ein is-Ausdruck des Musterabgleichs definitiv die Mustervariable im true-Zweig der if-Anweisung zuweist.The samples in this topic use the recommended construct where a pattern match is expression definitely assigns the match variable in the true branch of the if statement. Sie können die Logik umdrehen, indem Sie sagen, dass if (!(shape is Square s)) und die Variable s definitiv nur im false-Zweig zugewiesen seien.You could reverse the logic by saying if (!(shape is Square s)) and the variable s would be definitely assigned only in the false branch. Obwohl das in C# gültig ist, wird es nicht empfohlen, da diese Logik komplizierter ist.While this is valid C#, it is not recommended because it is more confusing to follow the logic.

Diese Regeln bedeuten, dass Sie wahrscheinlich nicht versehentlich auf das Ergebnis eines Musterabgleichausdrucks zugreifen, wenn das Muster nicht erfüllt wurde.These rules mean that you are unlikely to accidentally access the result of a pattern match expression when that pattern was not met.

Musterabgleich mit switch-AnweisungenUsing pattern matching switch statements

Im Laufe der Zeit müssen Sie vielleicht andere Formtypen unterstützen.As time goes on, you may need to support other shape types. Mit der steigenden Anzahl von Bedingungen, die Sie testen, werden Sie feststellen, dass die Verwendung der is-Musterabgleichausdrücke sehr umständlich werden kann.As the number of conditions you are testing grows, you'll find that using the is pattern matching expressions can become cumbersome. Zusätzlich zum Bedarf an if-Ausdrücken für jeden Typ, den Sie testen möchten, schränken die is-Ausdrücke das Testen ein, wenn die Eingabe mit einem einzigen Typ übereinstimmt.In addition to requiring if statements on each type you want to check, the is expressions are limited to testing if the input matches a single type. In diesem Fall stellen Sie fest, dass die Musterabgleichausdrücke switch zu einer besseren Wahl werden.In this case, you'll find that the switch pattern matching expressions becomes a better choice.

Die herkömmliche switch-Anweisung war ein Musterausdruck: Sie unterstützte das Konstantenmuster.The traditional switch statement was a pattern expression: it supported the constant pattern. Sie können eine Variable mit einer beliebigen Konstante vergleichen, die in einer case-Anweisung verwendet wird:You could compare a variable to any constant used in a case statement:

public static string GenerateMessage(params string[] parts)
{
    switch (parts.Length)
    {
        case 0:
            return "No elements to the input";
        case 1:
            return $"One element: {parts[0]}";
        case 2:
            return $"Two elements: {parts[0]}, {parts[1]}";
        default:
            return $"Many elements. Too many to write";
    }
}

Das einzige Muster, das von der switch-Anweisung unterstützt wurde, war das Konstantenmuster.The only pattern supported by the switch statement was the constant pattern. Sie war zudem auf numerische Typen und den string-Typ beschränkt.It was further limited to numeric types and the string type. Diese Einschränkungen wurden entfernt, und Sie können nun eine switch-Anweisung mit dem Typmuster schreiben:Those restrictions have been removed, and you can now write a switch statement using the type pattern:

public static double ComputeAreaModernSwitch(object shape)
{
    switch (shape)
    {
        case Square s:
            return s.Side * s.Side;
        case Circle c:
            return c.Radius * c.Radius * Math.PI;
        case Rectangle r:
            return r.Height * r.Length;
        default:
            throw new ArgumentException(
                message: "shape is not a recognized shape",
                paramName: nameof(shape));
    }
}

Die switch-Anweisung des Musterabgleichs verwendet ähnliche Syntax für Entwickler, die die switch-Anweisung im klassischen C-Stil verwendet haben.The pattern matching switch statement uses familiar syntax to developers who have used the traditional C-style switch statement. Jede case wird ausgewertet und der Code unterhalb der Bedingung, die mit der Eingabevariablen übereinstimmt, wird ausgeführt.Each case is evaluated and the code beneath the condition that matches the input variable is executed. Die Codeausführung kann nicht von einem case-Ausdruck in den nächsten „fortfahren“; die Syntax der case-Anweisung erfordert, dass jede case mit break, return oder goto endet.Code execution cannot "fall through" from one case expression to the next; the syntax of the case statement requires that each case end with a break, return, or goto.

Hinweis

Die goto-Anweisungen, die auf eine andere Bezeichnung springen, sind nur für das Konstantenmuster, die klassische switch-Anweisung, gültig.The goto statements to jump to another label are valid only for the constant pattern, the classic switch statement.

Es gibt wichtige neue Regeln für die switch-Anweisung.There are important new rules governing the switch statement. Die Beschränkungen für den Typ der Variablen im switch-Ausdruck sind entfernt worden.The restrictions on the type of the variable in the switch expression have been removed. Jeder Typ wie object in diesem Beispiel kann verwendet werden.Any type, such as object in this example, may be used. Die case-Ausdrücke sind nicht mehr auf konstante Werte beschränkt.The case expressions are no longer limited to constant values. Das Entfernen dieser Beschränkung bedeutet, dass das Neuanordnen von switch-Abschnitten das Verhalten eines Programms verändern kann.Removing that limitation means that reordering switch sections may change a program's behavior.

Solange sie auf konstante Werte beschränkt waren, konnte nicht mehr als eine case-Bezeichnung mit dem Wert des switch-Ausdrucks übereinstimmen.When limited to constant values, no more than one case label could match the value of the switch expression. Verbinden Sie das mit der Regel, das jeder switch-Abschnitt nicht im nächsten Abschnitt fortfahren darf, und daraus folgt, dass die switch-Abschnitte in jeder Reihenfolge neu angeordnet werden konnten, ohne das Verhalten zu beeinflussen.Combine that with the rule that every switch section must not fall through to the next section, and it followed that the switch sections could be rearranged in any order without affecting behavior. Nun spielt die Reihenfolge von jedem Abschnitt mit verallgemeinerten switch-Ausdrücken eine Rolle.Now, with more generalized switch expressions, the order of each section matters. Die switch-Ausdrücke werden in der Reihenfolge ausgewertet, in der sie im Text auftreten.The switch expressions are evaluated in textual order. Die Ausführung wechselt zur ersten switch-Bezeichnung, die mit dem switch-Ausdruck übereinstimmt.Execution transfers to the first switch label that matches the switch expression.
Beachten Sie, dass der default-case nur ausgeführt wird, wenn keine andere case-Bezeichnung übereinstimmt.Note that the default case will only be executed if no other case labels match. Der default-case wird zuletzt bewertet, unabhängig von der Reihenfolge im Text.The default case is evaluated last, regardless of its textual order. Wenn kein default-case existiert und keine anderen case-Ausdrücke übereinstimmen, wird die Ausführung an der Anweisung nach der switch-Anweisung fortgesetzt.If there is no default case, and none of the other case statements match, execution continues at the statement following the switch statement. Kein Code der case-Bezeichnungen wird ausgeführt.None of the case labels code is executed.

when-Klauseln in case-Ausdrückenwhen clauses in case expressions

Sie können Sonderfälle für diese Formen erstellen, die einen 0-Bereich haben, indem Sie eine when-Klausel in der case-Bezeichnung verwenden.You can make special cases for those shapes that have 0 area by using a when clause on the case label. Ein Quadrat mit einer Seitenlänge von 0 oder ein Kreis mit einem Radius von 0 hat einen 0-Bereich.A square with a side length of 0, or a circle with a radius of 0 has a 0 area. Sie geben diese Bedingung mithilfe einer when-Klausel für die case-Bezeichnung an:You specify that condition using a when clause on the case label:

public static double ComputeArea_Version3(object shape)
{
    switch (shape)
    {
        case Square s when s.Side == 0:
        case Circle c when c.Radius == 0:
            return 0;

        case Square s:
            return s.Side * s.Side;
        case Circle c:
            return c.Radius * c.Radius * Math.PI;
        default:
            throw new ArgumentException(
                message: "shape is not a recognized shape",
                paramName: nameof(shape));
    }
}

Diese Änderung veranschaulicht einige wichtige Punkte hinsichtlich der neuen Syntax.This change demonstrates a few important points about the new syntax. Zuerst können mehrere case-Bezeichnungen auf den switch-Abschnitt angewendet werden.First, multiple case labels can be applied to one switch section. Der Anweisungsblock wird ausgeführt, wenn eine dieser Bezeichnungen true ist.The statement block is executed when any of those labels is true. Wenn in diesem Fall der switch-Ausdruck entweder ein Kreis oder ein Quadrat mit einem 0-Bereich ist, gibt die Methode die Konstante 0 zurück.In this instance, if the switch expression is either a circle or a square with 0 area, the method returns the constant 0.

In diesem Beispiel werden zwei verschiedene Variablen in den zwei case-Bezeichnungen für den ersten switch-Block ausgeführt.This example introduces two different variables in the two case labels for the first switch block. Beachten Sie, dass die Anweisungen in diesem switch-Block weder die Variablen c (für den Kreis) noch s (für das Quadrat) verwenden.Notice that the statements in this switch block do not use either the variables c (for the circle) or s (for the square). Keine dieser Variablen wird definitiv in diesem switch-Block zugewiesen.Neither of those variables is definitely assigned in this switch block. Wenn einer der Fälle übereinstimmt, wurde eindeutig eine der Variablen zugewiesen.If either of these cases match, clearly one of the variables has been assigned. Allerdings ist es unmöglich zu sagen, welche während der Kompilierung zugewiesen wurde, da beide Fälle zur Laufzeit übereinstimmen könnten.However, it is impossible to tell which has been assigned at compile-time, because either case could match at runtime. Wenn Sie aus diesem Grund meistens mehrere case-Bezeichnungen für denselben Block verwenden, werden Sie keine neue Variable in die case-Anweisung einführen oder die Variable nur in der when-Klausel verwenden.For that reason, most times when you use multiple case labels for the same block, you won't introduce a new variable in the case statement, or you will only use the variable in the when clause.

Nachdem diese Formen mit 0-Bereich hinzugefügt wurden, werden wir ein paar weitere Formtypen einfügen: ein Rechteck und ein Dreieck:Having added those shapes with 0 area, let's add a couple more shape types: a rectangle and a triangle:

public static double ComputeArea_Version4(object shape)
{
    switch (shape)
    {
        case Square s when s.Side == 0:
        case Circle c when c.Radius == 0:
        case Triangle t when t.Base == 0 || t.Height == 0:
        case Rectangle r when r.Length == 0 || r.Height == 0:
            return 0;

        case Square s:
            return s.Side * s.Side;
        case Circle c:
            return c.Radius * c.Radius * Math.PI;
        case Triangle t:
            return t.Base * t.Height * 2;
        case Rectangle r:
            return r.Length * r.Height;
        default:
            throw new ArgumentException(
                message: "shape is not a recognized shape",
                paramName: nameof(shape));
    }
}

Dieser Satz von Änderungen fügt case-Bezeichnungen für den degenerierten case und Bezeichnungen und Blöcke für jede der neuen Formen hinzu.This set of changes adds case labels for the degenerate case, and labels and blocks for each of the new shapes.

Zuletzt können Sie einen null-case hinzufügen, um sicherzustellen, dass das Argument nicht null ist:Finally, you can add a null case to ensure the argument is not null:

public static double ComputeArea_Version5(object shape)
{
    switch (shape)
    {
        case Square s when s.Side == 0:
        case Circle c when c.Radius == 0:
        case Triangle t when t.Base == 0 || t.Height == 0:
        case Rectangle r when r.Length == 0 || r.Height == 0:
            return 0;

        case Square s:
            return s.Side * s.Side;
        case Circle c:
            return c.Radius * c.Radius * Math.PI;
        case Triangle t:
            return t.Base * t.Height * 2;
        case Rectangle r:
            return r.Length * r.Height;
        case null:
            throw new ArgumentNullException(paramName: nameof(shape), message: "Shape must not be null");
        default:
            throw new ArgumentException(
                message: "shape is not a recognized shape",
                paramName: nameof(shape));
    }
}

Der besondere Verhalten für das null-Muster ist interessant, weil die Konstante null im Muster keinen Typ besitzt, aber in jeden Verweis- oder Nullable-Typ konvertiert werden kann.The special behavior for the null pattern is interesting because the constant null in the pattern does not have a type but can be converted to any reference type or nullable type. Statt null in einen beliebigen Typ zu konvertieren, definiert die Sprache, dass ein null-Wert keinem Typmuster entspricht, unabhängig Typ zur Kompilierzeit der Variablen.Rather than convert a null to any type, the language defines that a null value will not match any type pattern, regardless of the compile-time type of the variable. Dieses Verhalten macht das neue switch-basierte Typmuster konsistent mit der is-Anweisung: is-Anweisungen geben stets false zurück, wenn der überprüfte Wert null ist.This behavior makes the new switch based type pattern consistent with the is statement: is statements always return false when the value being checked is null. Außerdem ist es einfacher: Nachdem Sie den Typ überprüft haben, ist keine zusätzliche NULL-Überprüfung erforderlich.It's also simpler: once you have checked the type, you don't need an additional null check. Das erkennen Sie daran, dass in keinem der Case-Blocks oben genannten Beispiele NULL-Überprüfungen durchgeführt werden: Sie sind schlicht nicht erforderlich, da der Abgleich des Typmusters einen Wert ungleich NULL garantiert.You can see that from the fact that there are no null checks in any of the case blocks of the samples above: they are not necessary, since matching the type pattern guarantees a non-null value.

varDeklarationen in case Ausdrückevar declarations in case expressions

Die Einführung von var als einer der Ausdrücke Übereinstimmung neue Regeln zur Musterübereinstimmung eingeführt.The introduction of var as one of the match expressions introduces new rules to the pattern match.

Die erste Regel ist, die die var Deklaration folgt den Typ "normal" Rückschlussregeln: der Typ werden von den statischen Typ des Switch-Ausdrucks abgeleitet wird.The first rule is that the var declaration follows the normal type inference rules: The type is inferred to be the static type of the switch expression. Von dieser Regel übereinstimmt immer mit dem Typ.From that rule, the type always matches.

Die zweite Regel ist, die eine var Deklaration keine Überprüfung auf null, der andere Typ Muster Ausdrücke enthalten.The second rule is that a var declaration does not have the null check that other type pattern expressions include. Bedeutet, dass die Variable kann null sein und eine null-Prüfung ist in diesem Fall erforderlich.That means the variable may be null, and a null check is necessary in that case.

Diese zwei Regeln bedeuten, dass in vielen Fällen eine var Deklaration in einem case Ausdruck übereinstimmt, die gleichen Bedingungen wie eine default Ausdruck.Those two rules mean that in many instances, a var declaration in a case expression matches the same conditions as a default expression. Da jeder Fall nicht standardmäßiger bevorzugt wird die default Fall die default Fall werden nie ausgeführt.Because any non-default case is preferred to the default case, the default case will never execute.

Hinweis

Der Compiler gibt keine Warnung in diesen Fällen, in denen eine default Fall geschrieben wurde, aber nie ausgeführt.The compiler does not emit a warning in those cases where a default case has been written but will never execute. Dies ist konsistent mit aktuellen switch Anweisung Verhalten, in denen alle möglichen Fälle eingestellt wurden.This is consistent with current switch statement behavior where all possible cases have been listed.

Die dritte Regel führt verwendet, in denen eine var Fall kann nützlich sein.The third rule introduces uses where a var case may be useful. Stellen Sie sich vor, dass Sie einen Mustervergleich ausführen, wobei die Eingabe eine Zeichenfolge ist und Sie bekannter Befehl Werten gesucht werden.Imagine that you are doing a pattern match where the input is a string and you are searching for known command values. Sie können Folgendes schreiben:You might write something like:

static object CreateShape(string shapeDescription)
{
    switch (shapeDescription)
    {
        case "circle":
            return new Circle(2);

        case "square":
            return new Square(4);
        
        case "large-circle":
            return new Circle(12);

        case var o when (o?.Trim()?.Length ?? 0) == 0:
            // whitespace
            return null;
        default:
            return "invalid shape description";
    }            
}

Die var Fall Übereinstimmungen null, die leere Zeichenfolge oder eine Zeichenfolge, die nur Leerzeichen enthält.The var case matches null, the empty string, or any string that contains only whitespace. Beachten Sie, die der obige Code verwendet die ?. Operator, um sicherzustellen, dass keine versehentlich ausgelöst wird, eine NullReferenceException.Notice that the preceding code uses the ?. operator to ensure that it does not accidentally throw a NullReferenceException. Die default -Fall verarbeitet, andere Zeichenfolgenwerte, die vom Befehlsparser für diesen nicht verstanden werden.The default case handles any other string values that are not understood by this command parser.

Dies ist ein Beispiel, in dem sollten Sie in Betracht ziehen einer var case-Ausdruck, der sich von einem default Ausdruck.This is one example where you may want to consider a var case expression that is distinct from a default expression.

ZusammenfassungConclusions

Musterabgleichkonstrukte helfen Ihnen, den Steuerungsfluss zwischen verschiedenen Variablen und Typen, die nicht durch eine Vererbungshierarchie verknüpft sind, einfach zu verwalten.Pattern Matching constructs enable you to easily manage control flow among different variables and types that are not related by an inheritance hierarchy. Sie können auch die Logik steuern, um jede Bedingung, die Sie testen, in der Variable zu verwenden.You can also control logic to use any condition you test on the variable. Das ermöglicht Ihnen Muster und Idiome, die Sie häufiger brauchen werden, wenn Sie mehr verteilte Anwendungen entwickeln, bei denen Daten und die Methoden, die diese Daten bearbeiten, getrennt sind.It enables patterns and idioms that you'll need more often as you build more distributed applications, where data and the methods that manipulate that data are separate. Sie werden bemerken, dass die Formstrukturen, die in diesem Beispiel verwendet wurden, keine Methoden enthält, sondern nur schreibgeschützte Eigenschaften.You'll notice that the shape structs used in this sample do not contain any methods, just read-only properties. Musterabgleich funktioniert mit jedem Datentyp.Pattern Matching works with any data type. Sie erstellen Ausdrücke, die das Objekt untersuchen und Steuerungsflussentscheidungen anhand dieser Bedingungen treffen.You write expressions that examine the object, and make control flow decisions based on those conditions.

Vergleichen Sie den Code in diesem Beispiel mit dem Entwurf, der aus dem Erstellen einer Klassenhierarchie für eine abstrakte Shape und spezifisch abgeleitete Formen folgen würde, von denen jede ihre eigene Implementierung einer virtuellen Methode hat, um den Bereich zu berechnen.Compare the code from this sample with the design that would follow from creating a class hierarchy for an abstract Shape and specific derived shapes each with their own implementation of a virtual method to calculate the area. Sie werden häufig feststellen, dass Musterabgleichausdrücke sehr nützlich sein können, wenn Sie mit Daten arbeiten und die Datenspeicherprobleme von den Verhaltensproblemen trennen möchten.You'll often find that pattern matching expressions can be a very useful tool when you are working with data and want to separate the data storage concerns from the behavior concerns.