Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Deklaration, Konstante und
Tip
Dieser Artikel ist Teil des Abschnitts "Grundlagen" für Entwickler, die bereits mindestens eine Programmiersprache kennen und C# erlernen. Beginnen Sie mit der Musterabgleichsübersicht , wenn Sie zuvor noch keine C#-Muster verwendet haben. Vollständige Sprachregeln finden Sie in der Musterreferenz.
Ein Muster wird auf einen Eingabeausdruck angewendet. C# wertet den Ausdruck aus; anschließend testet das Muster den resultierenden Wert oder bindet ihn. Deklaration, Konstante und var Muster beantworten drei praktische Fragen:
- Deklarationsmuster: Hat der Ausdruck einen Nicht-Null-Wert eines kompatiblen Laufzeittyps ergeben? Deklarieren Sie in diesem Falls eine Variable für diesen Wert.
- Konstantenmuster: Hat der Ausdruck einen bestimmten Konstantenwert erzeugt?
-
varMuster: Welcher Wert hat der Ausdruck erzeugt? Erfassen Sie sie, ohne zuerst ihren Typ oder Wert zu testen.
Testen und Erfassen eines Typs mit einem Deklarationsmuster
Ein Deklarationsmuster besteht aus einem Typ und einer Bezeichnung. Der Typ gibt an, welcher Laufzeittyp getestet werden soll. Die Bezeichnung deklariert die Variable, die den übereinstimmenden Wert empfängt.
Das folgende Beispiel erhält ein object, weshalb der Ausdruck viele verschiedene Typen erzeugen kann. Mit dem Deklarationsmuster kann die übereinstimmende Verzweigung einen Dezimalwert ohne separaten Typtest verwenden und umwandeln:
static void PrintPrice(object value)
{
if (value is decimal amount)
{
Console.WriteLine($"Price: {amount:C}");
}
}
In value is decimal amount:
-
valueist der Eingabeausdruck. C# wertet sie zuerst aus. -
decimalist der getestete Typ. Das Muster passt, wenn der ausgewertete Wert nicht NULL ist und sein Laufzeittyp mitdecimalkompatibel ist. -
amountist die Bezeichnung. Wenn das Muster übereinstimmt, wirdamountdeklariert und ihm der Dezimalwert zugewiesen.
Der Compiler verfolgt nach, ob eine lokale Variable vor dem Lesen des Codes einen Wert empfängt. Diese Nachverfolgung wird als eindeutige Zuordnung bezeichnet. Innerhalb des if Blocks weiß der Compiler, dass amount zugewiesen wurde, da der Block nur ausgeführt wird, wenn das Muster übereinstimmt. Der Compiler erzeugt einen Fehler, wenn Ihr Code versucht, außerhalb des if Blocks zuzugreifenamount. Wenn value kein decimal-Wert ist, wird der Variablen amount kein Wert zugewiesen.
Wählen Sie ein Deklarationsmuster aus, wenn die übereinstimmende Verzweigung das Ergebnis als getesteten Typ verwenden muss. Sie kombiniert die Test-, Konvertierungs- und Variablendeklaration, wodurch verhindert wird, dass der Ausdruck wiederholt oder eine separate Umwandlung geschrieben wird.
Sie können auch Deklarationsmuster verwenden, wenn ein Ausdruck möglicherweise mehrere nützliche Typen erzeugt:
static string FormatSensorValue(object reading) =>
reading switch
{
int count => $"Count: {count}",
double temperature => $"Temperature: {temperature:F1}°C",
string message => $"Message: {message}",
_ => "Unsupported reading"
};
Jeder Arm deklariert eine Variable des übereinstimmenen Typs, da das Ergebnis das Formatierungsverhalten dieses Typs benötigt. Ein Deklarationsmuster stimmt nur überein, wenn der ausgewertete Wert ungleich NULL ist und bereits über einen Laufzeittyp verfügt, der mit dem getesteten Typ über die für Muster zulässigen Konvertierungen kompatibel ist.
null hat keinen Laufzeittyp, damit das Muster übereinstimmen kann. Das Muster führt auch keine benutzerdefinierten Konvertierungsoperatoren aus: Es ist ein Typtest und eine Erfassung, keine Anforderung zum Konvertieren des Werts in einen anderen Typ. Die vollständigen Kompatibilitätsregeln finden Sie unter Deklarations- und Typmuster.
Abgleichen eines bestimmten Werts mit einem Konstantenmuster
Ein Konstantenmuster testet, ob ein Ausdruck eine bestimmte Konstante erzeugt, z. B. eine Zahl, eine Zeichenfolge, ein boolesches Element, ein Enumerationselement, einen deklarierten Wert oder nulleinen deklarierten const Wert.
Konstantenmuster passen zu einem Schalterausdruck, wenn jeweils mehrere bekannte Werte ein anderes Ergebnis erzeugen:
static string GetCommandMessage(Command command) =>
command switch
{
Command.Start => "Starting",
Command.Stop => "Stopping",
Command.Pause => "Pausing",
_ => "Unknown command"
};
Command ist ein enum, ein Typ, der eine Menge benannter Konstanten definiert.
Command.Start, Command.Stopund Command.Pause sind seine Enumerationsmember, sodass jeder Schalterarm ein konstantes Muster verwendet, um einen benannten Befehlswert zu testen.
Wählen Sie dieses Formular aus, wenn der Befehl mehrere diskrete Bedeutungen haben kann. Die Schalterarme halten die Werte und ihre Ergebnisse zusammen. Für einen einfachen Gleichheitsvergleich ist eine if-Anweisung wie if (command == Command.Start) in der Regel leichter zu lesen.
Bei konstanten Mustervergleichen werden integrierte Regeln zur Sprachgleichheit anstelle eines benutzerdefinierten == Operators verwendet. Ausführliche Gleichheits- und Konvertierungsregeln finden Sie in der Konstantenmusterreferenz.
Das null Konstantenmuster ist nützlich für eine zuverlässige NULL-Prüfung:
static bool HasText(string? text) => text is not null;
Wählen Sie is null den Nullstatus aus, oder is not null überprüfen Sie den Nullstatus. Diese Muster rufen keinen benutzerdefinierten Gleichheitsoperator auf, auch wenn der Typ des Ausdrucks == überlädt.
Ein Ergebnis für einen Guard mit var-Muster erfassen
Ein var Muster entspricht jedem Ergebnis, einschließlich nullund deklariert eine Variable, deren Typ der Kompilierungszeit des Eingabeausdrucks ist. Er kann einen berechneten Wert erfassen, während ein anderes Muster bereits einem Objekt entspricht:
static string GetDeliveryMessage(object delivery) =>
delivery switch
{
ExpressDelivery express
when EstimateDays(express) is var days && days <= 2
=> $"Arrives in {days} day{(days == 1 ? "" : "s")}",
ExpressDelivery => "Express delivery for your location takes more than two days",
_ => "Standard delivery"
};
static int EstimateDays(ExpressDelivery delivery) =>
delivery.MilesAway <= 500 ? 1 :
delivery.MilesAway <= 1_000 ? 2 : 3;
record ExpressDelivery(int MilesAway);
Das Deklarationsmuster ExpressDelivery express erfasst zunächst das Übermittlungsobjekt als express. Der Methodenaufruf EstimateDays(express) ist der Eingabeausdruck für das var Muster. C# wertet diesen Methodenaufruf aus, und var days erfasst die daraus resultierende Schätzung als days, ohne deren Typ oder Wert zu überprüfen. Die Schätzung kann ein oder zwei Tage sein, wenn der Wächter erfolgreich ist. Das Arm-Ergebnis benötigt den erfassten Wert, um die tatsächliche Anzahl der Tage anzugeben.
Eine normale lokale Variable kann nicht zwischen einem Switch-Arm-Muster und seinem when Schutz deklariert werden. Ein erneuter Aufruf von EstimateDays(express) im Ergebnis würde die Berechnung wiederholen. Wählen Sie dieses var Musterformular aus, wenn der Code bereits abgleicht, und sowohl der Guard als auch das Ergebnis benötigen einen berechneten Zwischenwert.
Wenn Sie den erfassten Wert nicht benötigen, verwenden Sie das Verwerfen-Muster _ , anstatt eine Variable zu deklarieren.