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.
Deklaracja, stała i
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#. Zacznij od przeglądu dopasowania wzorca , jeśli wcześniej nie użyto wzorców języka C#. Aby zapoznać się z pełnymi zasadami języka, zobacz dokumentację wzorców.
Wzorzec jest stosowany do wyrażenia wejściowego. Język C# oblicza wyrażenie, a następnie testuje wzorzec lub przechwytuje wynikową wartość. Deklaracja, stała i wzorce var odpowiadają na trzy praktyczne pytania:
- Wzorzec deklaracji: Czy wyrażenie zwróciło wartość inną niż null o zgodnym typie środowiska uruchomieniowego? Jeśli tak, zadeklaruj zmienną dla tej wartości.
- Wzorzec stałej: Czy wyrażenie wygenerowało jedną konkretną wartość stałą?
-
varwzorzec: Jaka wartość została wygenerowana przez wyrażenie? Przechwyć go bez wcześniejszego testowania jego typu lub wartości.
Testowanie i przechwytywanie typu za pomocą wzorca deklaracji
Wzorzec deklaracji składa się z typu i oznaczenia. Typ określa typ czasu wykonywania do przetestowania. Oznaczenie deklaruje zmienną, która odbiera zgodną wartość.
Poniższy przykład otrzymuje element object, więc wyrażenie może generować wiele różnych typów. Wzorzec deklaracji umożliwia gałęziom dopasowywania użycie wartości dziesiętnej bez oddzielnego testu typu i rzutowania:
static void PrintPrice(object value)
{
if (value is decimal amount)
{
Console.WriteLine($"Price: {amount:C}");
}
}
W pliku value is decimal amount:
-
valuejest wyrażeniem wejściowym. Język C# ocenia go jako pierwszy. -
decimaljest testowanym typem. Wzorzec jest zgodny, gdy obliczona wartość ma wartość inną niż null, a jego typ czasu wykonywania jest zgodny z parametremdecimal. -
amountjest oznaczeniem. Gdy wzorzec jest zgodny, deklarujeamounti przypisuje do niego wartość dziesiętną.
Kompilator śledzi, czy zmienna lokalna otrzymuje wartość, zanim kod go odczytuje. To śledzenie jest nazywane określonym przypisaniem. Wewnątrz bloku if kompilator wie, że amount ma przypisaną wartość, ponieważ kod w tym bloku jest wykonywany tylko wtedy, gdy nastąpi dopasowanie do wzorca. Kompilator generuje błąd, jeśli kod próbuje uzyskać dostęp amount poza blokiem if . Jeśli value nie jest wartością decimal , zmienna amount nie jest przypisana do wartości.
Wybierz wzorzec deklaracji, gdy odpowiednia gałąź musi używać wyniku jako testowanego typu. Łączy sprawdzenie, konwersję i deklarację zmiennej, co pozwala uniknąć powtarzania wyrażenia lub stosowania osobnego rzutowania.
Można również użyć wzorców deklaracji, gdy jedno wyrażenie może wygenerować kilka przydatnych typów:
static string FormatSensorValue(object reading) =>
reading switch
{
int count => $"Count: {count}",
double temperature => $"Temperature: {temperature:F1}°C",
string message => $"Message: {message}",
_ => "Unsupported reading"
};
Każde ramię deklaruje zmienną o dopasowanym typie, ponieważ wynik musi korzystać z formatowania właściwego dla tego typu. Wzorzec deklaracji pasuje tylko wtedy, gdy ewaluowana wartość nie ma wartości null i ma już w czasie wykonywania typ zgodny z testowanym typem poprzez konwersje dozwolone dla wzorców.
null nie ma typu czasu wykonywania dla wzorca, który ma być zgodny. Wzorzec nie uruchamia również operatorów konwersji zdefiniowanych przez użytkownika: jest to test typu i przechwytywanie, a nie żądanie konwersji wartości na inny typ. Aby uzyskać pełne reguły zgodności, zobacz Deklaracje i wzorce typów.
Dopasuj określoną wartość do stałego wzorca
Stały wzorzec sprawdza, czy wyrażenie generuje konkretną stałą, taką jak liczba, ciąg, wartość logiczna, składowa wyliczenia, zadeklarowana const wartość lub null.
Wzorce stałe pasują do wyrażenia przełącznika, gdy kilka znanych wartości generuje inny wynik:
static string GetCommandMessage(Command command) =>
command switch
{
Command.Start => "Starting",
Command.Stop => "Stopping",
Command.Pause => "Pausing",
_ => "Unknown command"
};
Command jest typem wyliczeniowym, który definiuje zbiór nazwanych stałych.
Command.Start, Command.Stopi Command.Pause są jego składowe wyliczenia, więc każde ramię przełącznika używa stałego wzorca do testowania jednej nazwanej wartości polecenia.
Wybierz ten formularz, gdy polecenie może mieć kilka odrębnych znaczenia. Ramiona przełącznika zachowują wartości i ich wyniki razem. W przypadku pojedynczego prostego porównania równości instrukcja if, taka jak if (command == Command.Start), jest zwykle łatwiejsza w odczycie.
Dopasowywanie do stałego wzorca wykorzystuje wbudowane w język reguły równości, a nie operator == zdefiniowany przez użytkownika. Aby uzyskać szczegółowe reguły równości i konwersji, zobacz odwołanie do stałego wzorca.
Wzorzec stałej null służy do niezawodnego sprawdzania wartości null:
static bool HasText(string? text) => text is not null;
Wybierz is null lub is not null podczas sprawdzania stanu null. Te wzorce nie wywołują operatora porównania równości zdefiniowanego przez użytkownika, nawet jeśli typ wyrażenia przeciąża operator ==.
Przechwytywanie wyniku ochrony za pomocą var wzorca
var wzorzec pasuje do każdego wyniku, łącznie z null, i deklaruje zmienną, której typem jest typ wyrażenia wejściowego w czasie kompilacji. Może przechwytywać obliczoną wartość, podczas gdy inny wzorzec już pasuje do obiektu:
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);
Wzorzec deklaracji ExpressDelivery express najpierw przechwytuje obiekt delivery jako express. Wywołanie metody EstimateDays(express) jest wyrażeniem wejściowym dla wzorca var. Język C# oblicza to wywołanie metody, a var days przypisuje uzyskane oszacowanie do days bez sprawdzania jego typu ani wartości. Szacowany czas może wynosić jeden lub dwa dni, jeśli mechanizm ochronny zadziała pomyślnie. Wynik gałęzi wymaga przechwyconej wartości, aby podać rzeczywistą liczbę dni.
Nie można zadeklarować zwykłej zmiennej lokalnej między wzorcem przełącznika i jego when osłoną. Ponowne wywołanie EstimateDays(express) w wyrażeniu wynikowym spowodowałoby ponowne wykonanie obliczenia. Wybierz ten var formularz wzorca, gdy kod jest już zgodny, a zarówno ochrona, jak i wynik wymagają obliczonej wartości pośredniej.
Jeśli nie potrzebujesz przechwyconej wartości, użyj wzorca odrzucającego _ zamiast deklarować zmienną.