Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Porada
Ten artykuł jest częścią sekcji Podstawy dla deweloperów, którzy już znają co najmniej jeden język programowania i uczą się języka C#. Jeśli dopiero zaczynasz programować, najpierw zacznij od samouczków Wprowadzenie . Doświadczeni deweloperzy języka C# mogą używać odwołań do wzorców dla pełnej składni i reguł.
Pochodzi z innego języka? Wzorce języka C# pełnią rolę podobną do dopasowywania wzorców Java i przypadków Pythonmatch. Język C# używa wzorców w is wyrażeniach, switch instrukcjach i switch wyrażeniach.
Dopasowywanie wzorca stosuje wzorzec do wyrażenia. Wzorzec to warunek testowania wyrażenia wejściowego. Dane wejściowe wzorca to to wyrażenie. Język C# oblicza wyrażenie wejściowe; wynik jest obliczoną wartością. Wzorzec sprawdza, czy ta wartość ma określony typ, jest równa określonej wartości, czy ma określony kształt. Gdy wzorzec jest zgodny, kod może używać informacji poznanych przez test, takich jak bardziej konkretny typ lub wartość wyodrębniona z obiektu.
Można użyć wzorca w trzech kontekstach:
- Po prawej stronie
isoperatora. - W etykiecie instrukcji
caseswitch. - W ramieniu wyrażenia
switch.
Wzorce są często bardziej przejrzyste niż ciąg instrukcji porównujących, ponieważ każda gałąź opisuje dane, które obsługuje. Na przykład poniższa metoda używa wyrażenia switch, aby wybrać komunikat o dostawie:
static string GetDeliveryMessage(Delivery? delivery) =>
delivery switch
{
null => "No delivery was scheduled.",
ExpressDelivery express => $"Express package {express.TrackingCode}",
StandardDelivery { Days: <= 2 } => "Standard delivery arriving soon",
_ => "Standard delivery"
};
Wzorce cykliczne mają własne wyrażenia wejściowe. W StandardDelivery { Days: <= 2 } wzorzec zewnętrzny otrzymuje wyrażenie delivery. Wzorzec rekurencyjny <= 2 otrzymuje wyrażenie właściwości Days z dopasowanego obiektu StandardDelivery.
Wyrażenie przed switch jest wyrażeniem wejściowym. Każda linia wewnątrz nawiasów klamrowych jest ramieniem przełącznika. Wzorzec zostanie wyświetlony przed elementem =>, a wynik pojawi się po nim. Język C# oblicza wartość wyrażenia wejściowego, a następnie wybiera pierwsze ramię, zgodnie z kolejnością w tekście, którego wzorzec jest zgodny i którego opcjonalny warunek when ma wartość true. Opcjonalny warunek ochronny when jest dodatkowym warunkiem boolowskim zapisanym po wzorcu. W poprzednim przykładzie pokazano następujące wzorce:
-
nulljest stałym wzorcem. Sprawdza, czydeliverywyrażenie daje wartośćnull. -
ExpressDelivery expressjest wzorcem deklaracji z dwiema częściami.ExpressDeliveryto część badania typu. Sprawdza, czy wartość oceniana jest obiektem niebędącym wartością null, którego typ czasu wykonywania jest zgodny z elementemExpressDelivery.expressto oznaczenie zmiennej: deklaruje zmienną o nazwieexpressi przypisuje do niej dopasowanyExpressDeliveryobiekt. -
StandardDelivery { Days: <= 2 }rozpoczyna się od testu typu.StandardDeliverysprawdza, czy wartość oceniana jest obiektem o wartości innej niż null tego typu. Nawiasy klamrowe zawierają wzorzec właściwości.Daysokreśla nazwę właściwości do sprawdzenia, więc wyrażenie właściwościDaysstaje się elementem wejściowym dla wzorca rekurencyjnego. Część<= 2jest wzorcem relacyjnym, który sprawdza, czy obliczona wartość jest mniejsza, czy równa2. -
_(podkreślenie) to wzorzec odrzucania. Pasuje do każdej obliczonej wartości, w tymnull. Ponieważ wcześniejsze ramiona już obsługująnull, dostawy ekspresowe oraz standardowe dostawy docierające w ciągu dwóch dni, to ostatnie ramię obsługuje każdą pozostałą wartość.
Ramię bez osłony when jest niestrzeżone. Wszystkie ramiona w pierwszym przykładzie są niestrzeżone. Jeśli wcześniej niestrzeżone ramię pasuje do każdej obliczonej wartości, którą może dopasować późniejsza ramię, późniejsze ramię jest podsumowywane. Wzorzec podsumowany jest taki, w którym każda możliwa wartość wejściowa zgodna została już dopasowana przez wcześniejsze ramię przełącznika. Nigdy nie może być zgodna, więc kompilator zgłasza błąd. Gałąź odrzucająca (_) musi być ostatnia, ponieważ dopasowuje się do każdego wyrażenia wejściowego. Chronione ramię nie subsumuje późniejszego ramienia na podstawie samego wzorca, ponieważ strażnik może być false.
Wyrażenie przełącznika jest wyczerpujące , gdy jego ramiona obsługują każde możliwe wyrażenie wejściowe. Pierwszy przykład jest pełny, ponieważ jego ostatnia gałąź odrzucająca obsługuje wszystko, czego nie dopasują wcześniejsze gałęzie. Kompilator ostrzega, gdy wykrywa potencjalną wartość wejściową, której nie obsługuje żadna gałąź. Kompilator nie może udowodnić wyczerpującości dla każdej kombinacji wzorców, ale ta diagnostyka ułatwia pisanie poprawnego kodu pasującego do wzorca. Aby uzyskać szczegółowe informacje na temat dopasowywania, podsumpcji i reguł wyczerpującości, zobacz dokumentację wzorców.
Testowanie jednego warunku za pomocą polecenia is
is Użyj operatora, jeśli potrzebujesz jednego testu logicznego. Poniższy kod oblicza wartość wyrażenia delivery i stosuje wzorzec deklaracji ExpressDelivery express. Część typu pasuje, gdy obliczana wartość jest różna od null, a jej typ w czasie wykonywania jest zgodny z ExpressDelivery. Gdy wzorzec jest zgodny, jego oznaczenie zmiennej deklaruje :express
static void PrintTrackingCode(Delivery delivery)
{
if (delivery is ExpressDelivery express)
{
Console.WriteLine($"Track express package {express.TrackingCode}");
}
}
Kompilator śledzi, czy do zmiennej lokalnej przypisano wartość, zanim kod odczyta jej wartość. To śledzenie jest nazywane określonym przypisaniem. Wewnątrz bloku if warunek może mieć wartość true tylko wtedy, gdy wzorzec przypisał pasujący obiekt do express. W związku z tym kompilator wie, że express jest tam zdecydowanie przypisany. Kod może bezpiecznie używać jego TrackingCode właściwości. Nie potrzebujesz oddzielnej obsady. Jeśli potrzebujesz tylko testu typu i nie musisz deklarować zmiennej, użyj wzorca typu, takiego jak delivery is ExpressDelivery.
Użyj polecenia is null lub is not null w przypadku sprawdzania wartości null. Te wzorce nie wywołują operatora == ani != zdefiniowanego przez użytkownika.
static void PrintPackageStatus(Delivery? delivery)
{
if (delivery is null)
{
Console.WriteLine("No package is available.");
}
else
{
Console.WriteLine("A package is ready to track.");
}
}
Aby uzyskać więcej wskazówek dotyczących bezpiecznej obsługi wartości null, zobacz typy referencyjne dopuszczające wartość null.
Wybieranie między instrukcją a wyrażeniem
Wzorce działają z obiema formami switch:
- Użyj instrukcji
switch, gdy każde dopasowanie powinno uruchamiać co najmniej jedną instrukcję. -
switchUżyj wyrażenia, gdy każde dopasowanie powinno wygenerować wartość.
Poniższa instrukcja switch informuje o aktualizacji dostawy. Gałąź express-delivery zapisuje dwa komunikaty, więc instrukcja pasuje naturalnie:
static void PrintDeliveryUpdate(Delivery? delivery)
{
switch (delivery)
{
case null:
Console.WriteLine("No delivery was scheduled.");
break;
case ExpressDelivery express:
Console.WriteLine($"Express delivery {express.TrackingCode} is ready.");
Console.WriteLine("Notify the priority desk.");
break;
case StandardDelivery standard:
Console.WriteLine($"Standard delivery arrives in {standard.Days} days.");
break;
default:
Console.WriteLine("Another delivery type is scheduled.");
break;
}
}
Każde case stosuje wzorzec do wyrażenia delivery. Sekcja dopasowania może uruchamiać dowolną liczbę instrukcji przed break zamknięciem przełącznika. Sekcja default obsługuje wszystkie elementy, które nie są zgodne z wcześniejszymi przypadkami.
Następujące wyrażenie przełącznika if / else if zastępuje łańcuch, który przypisuje jeden wynik:
static string GetStatusMessage(StandardDelivery delivery) =>
delivery.Days switch
{
0 => "Delivered today",
1 => "Arriving tomorrow",
<= 3 => "Arriving soon",
_ => "In transit"
};
Wyrażenie przełącznika jest zwięzłe, ponieważ każde ramię ma ten sam cel: generuj zwróconą wartość. Użyj instrukcji switch, gdy gałęzie wykonują operacje, a wyrażenia switch, gdy gałęzie obliczają jeden wynik.
Kategorie wzorów
Język C# zawiera wzorce typowych rodzajów testów danych:
| Kategoria wzorca | Co testuje |
|---|---|
Deklaracja, stała i var wzorce |
Typ czasu wykonywania, określona wartość stała lub dowolna wartość, którą chcesz przechwycić |
| Wzorce typów | Typ czasu wykonywania bez deklarowania zmiennej |
| Wzorce właściwości i wzorce pozycyjne | Właściwości, pola lub dekonstrukturowane wartości |
| Wzorce relacyjne i logiczne | Porównania i kombinacje, takie jak and, ori not |
| Wzorce listy | Wartości i kształt listy lub tablicy |
| Odrzuć wzorce i odrzucenia | Dowolna pozostała wartość lub wartość, która kod celowo ignoruje |
Artykuły z serii Podstawy, do których prowadzą linki w tabeli, zawierają szczegółowe omówienie kategorii obecnie opisanych w tej sekcji. Aby uzyskać pełną składnię i przykłady dla wszystkich kategorii wzorców, zobacz dokumentację wzorców.