Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
11.1 Obecné
Vzor je syntaktická forma, kterou lze použít s operátorem is (§12.15.12) v switch_statement (§13.8.3) a v switch_expression (§12.12) vyjádřit tvar dat, s nímž se mají porovnávat příchozí data. Vzory můžou být rekurzivní, takže se části dat můžou shodovat s dílčími vzory.
Model se testuje s hodnotou v řadě kontextů:
- V příkazu switch se vzor popisku případu testuje s výrazem příkazu switch.
- V operátoru is-pattern je vzor na pravé straně testován proti výrazu vlevo.
- Ve výrazu switch se vzorswitch_expression_arm testuje s výrazem na levé straně výrazu switch-expression.
- V vnořených kontextech se dílčí vzor testuje na základě hodnot načtených z vlastností, polí nebo indexovaných z jiných vstupních hodnot v závislosti na formuláři vzoru.
Hodnota, proti které se testuje, se nazývá vstupní hodnota vzoru.
11.2 Vzorové formuláře
11.2.1 Obecné
Vzor může mít jednu z následujících forem:
pattern
: logical_pattern
;
primary_pattern
: parenthesized_pattern
| declaration_pattern
| constant_pattern
| var_pattern
| positional_pattern
| property_pattern
| discard_pattern
| type_pattern
| relational_pattern
;
parenthesized_pattern
: '(' pattern ')'
;
V produkčním '(' pattern ')' prostředí je možné model uzavřít do závorek, aby bylo možné vynutit pořadí vyhodnocení mezi vzory zkombinovaným pomocí jednoho z logical_patterns.
Některé vzorymůžou vést k deklaraci místní proměnné.
Každý formulář vzoru definuje sadu typů pro vstupní hodnoty, na které lze vzor použít. Vzor P se vztahuje na typ T , pokud T patří mezi typy, jejichž hodnoty se vzor může shodovat. Jedná se o chybu v době kompilace, pokud se v programu objeví vzorP, který odpovídá vstupní hodnotě vzoru (§11.1 pokud T není použitelný pro P.
Příklad: Následující příklad vygeneruje chybu v době kompilace, protože typ
vkompilace jeTextReader. Proměnná typuTextReadernemůže mít nikdy hodnotu, která je kompatibilní sstring:TextReader v = Console.In; // compile-time type of 'v' is 'TextReader' if (v is string) // compile-time error { // code assuming v is a string }Následující však nevygeneruje chybu v době kompilace, protože typ
vkompilace jeobject. Proměnná typuobjectmůže mít hodnotu, která je kompatibilní sstring:object v = Console.In; if (v is string s) { // code assuming v is a string }konec příkladu
Každý formulář vzoru definuje sadu hodnot, pro které vzor odpovídá hodnotě za běhu.
Pořadí vyhodnocení operací a vedlejších účinků během porovnávání vzorů (volání Deconstruct, přístupů k vlastnostem a vyvolání metod v System.ITuple) není zadáno.
11.2.2 Model deklarace
Declaration_pattern slouží k otestování, že hodnota má daný typ, a pokud je test úspěšný, volitelně zadat hodnotu v proměnné tohoto typu.
declaration_pattern
: type simple_designation
;
simple_designation
: discard_designation
| single_variable_designation
;
discard_designation
: '_'
;
single_variable_designation
: identifier
;
Simple_designation s tokenem _ se považuje za discard_designation, nikoli single_variable_designation.
Typ modulu runtime hodnoty se testuje s typem ve vzoru pomocí stejných pravidel uvedených v operátoru is-type (§12.15.12.1). Pokud je test úspěšný, vzor odpovídá této hodnotě. Jedná se o chybu v době kompilace, pokud je typ hodnoty null (§8.3.12) nebo odkazový typ s možnou hodnotou null (§8.9.3). Tento vzorový formulář nikdy neodpovídá hodnotě null .
Poznámka: Výraz is-type
e is Ta vzore is T _deklarace jsou ekvivalentní, pokudTnení typu s možnou hodnotou null. koncová poznámka
Při zadání vzorové vstupní hodnoty (§11.1) e, pokud je simple_designationdiscard_designation, označuje zahození (§9.2.9.2) a hodnota e není nijak vázána. (I když deklarovaná proměnná s názvem _ může být v tomto okamžiku v oboru, tato pojmenovaná proměnná se v tomto kontextu nezobrazí.) Pokud je simple_designationsingle_variable_designation, zanese se místní proměnná (§9.2.9) daného typu pojmenovaného daným identifikátorem. Tato místní proměnná má přiřazenou hodnotu vstupní hodnoty vzoru, pokud vzor odpovídá hodnotě.
Určité kombinace statického typu vstupní hodnoty vzoru a daného typu jsou považovány za nekompatibilní a výsledkem chyby v době kompilace. Hodnota statického typu E je oznamována jako vzor kompatibilní s typem T , pokud existuje převod identity, implicitní nebo explicitní převod odkazu, převod boxingu, převod rozbalení nebo implicitní nebo explicitní převod typu hodnoty null z E na T, nebo je-li otevřený ET typ (§8.4.3). Deklarace vzoru pojmenování typu T je použitelná pro každý typ E , pro který E je vzor kompatibilní s T.
Poznámka: Podpora otevřených typů může být nejužitečnější při kontrole typů, které mohou být buď struktury, nebo typy tříd, a boxování je třeba se vyhnout. koncová poznámka
Příklad: Model deklarace je užitečný pro provádění testů typů běhu referenčních typů a nahrazuje idiom.
var v = expr as Type; if (v != null) { /* code using v */ }s mírně stručnější
if (expr is Type v) { /* code using v */ }konec příkladu
Příklad: Vzor deklarace lze použít k otestování hodnot typů s možnou hodnotou null: hodnota typu (nebo boxed
Nullable<T>) odpovídá vzoruTT2 idtypu, pokud hodnota není null aT2jeT, nebo některé základního typu nebo rozhraníT. Například v fragmentu kóduint? x = 3; if (x is int v) { /* code using v */ }Podmínka
ifpříkazu jetrueza běhu a proměnnávobsahuje hodnotu3typuintuvnitř bloku. Po bloku je proměnnávv oboru, ale rozhodně není přiřazena. konec příkladu
11.2.3 Konstantní vzor
Constant_pattern se používá k otestování hodnoty vstupní hodnoty vzoru (§11.1) s danou konstantní hodnotou.
constant_pattern
: constant_expression
;
Konstantní vzor P se vztahuje na typ T , pokud existuje implicitní převod z konstantního výrazu P na typ T.
U konstantního vzoru Pje převedená hodnota
- je-li typ vstupní hodnoty vzoru celočíselný typ nebo výčtový typ, konstantní hodnota vzoru převedena na tento typ; jinak
- pokud typ vstupní hodnoty vzoru je nullable verze celočíselného typu nebo výčtu typ, konstantní hodnota vzoru převedena na jeho základní typ; jinak
- hodnota konstantní hodnoty vzoru.
Při zadání vstupní hodnoty vzoru e a konstantního vzoru P s převedenou hodnotou v,
- pokud e má celočíselný typ nebo výčtový typ nebo nulovou formu jednoho z nich a v má celočíselný typ, vzor
Podpovídá hodnotě e, pokud jee == vvýsledek výrazutrue; - vzor
Podpovídá hodnotě e, pokud se vrátíobject.Equals(e, v).true
Příklad: Příkaz
switchv následující metodě používá pět konstantních vzorů v popiscích písmen.static decimal GetGroupTicketPrice(int visitorCount) { switch (visitorCount) { case 1: return 12.0m; case 2: return 20.0m; case 3: return 27.0m; case 4: return 32.0m; case 0: return 0.0m; default: throw new ArgumentException(...); } }konec příkladu
11.2.4 Vzor var
Var_pattern odpovídá každé hodnotě. To znamená, že operace porovnávání vzorů s var_pattern vždy proběhne úspěšně.
Var_pattern platí pro každý typ.
var_pattern
: 'var' designation
;
designation
: simple_designation
| tuple_designation
;
tuple_designation
: '(' designations? ')'
;
designations
: designation (',' designation)*
;
Při zadání vzorové vstupní hodnoty (§11.1) e, pokud je označenídiscard_designation, označuje zahození (§9.2.9.2) a hodnota e není vázána na nic. (I když deklarovaná proměnná s tímto názvem může být v tomto okamžiku v oboru, tato pojmenovaná proměnná se v tomto kontextu nezobrazí.) V opačném případě, pokud je označenísingle_variable_designation, je hodnota e vázána na nově zavedenou místní proměnnou (§9.2.9) tohoto názvu, jehož typ je statickým typem e, a vstupní hodnota vzoru je přiřazena k této místní proměnné.
Jedná se o chybu, pokud by se název var sváže s typem, ve kterém se používá var_pattern .
Je-li označenítuple_designation, je vzor ekvivalentní positional_pattern (§11.2.5) (var formuláře, ...
) kde jsou označenínalezena v tuple_designation. Například vzor var (x, (y, z)) je ekvivalentní (var x, (var y, var z)).
11.2.5 Poziční vzor
Positional_pattern zkontroluje, zda vstupní hodnota není null, vyvolá odpovídající Deconstruct metodu (§12.7) a provede další porovnávání vzorů s výslednými hodnotami. Podporuje také syntaxi vzoru řazenou kolekci členů (bez zadaného typu), pokud je typ vstupní hodnoty stejný jako typ obsahující Deconstruct, nebo pokud typ vstupní hodnoty je typ řazené kolekce členů, nebo pokud typ vstupní hodnoty je object nebo System.ITuple a typ modulu runtime výraz implementuje System.ITuple.
positional_pattern
: type? '(' subpatterns? ')' property_subpattern? simple_designation?
;
subpatterns
: subpattern (',' subpattern)*
;
subpattern
: pattern
| subpattern_name ':' pattern
;
subpattern_name
: identifier
| subpattern_name '.' identifier
;
Vzhledem k porovnání vstupní hodnoty spodpatterny(typu) vzoru je metoda vybrána tak, že vyhledá v typu přístupné deklarace Deconstruct a vybere jednu z nich pomocí stejných pravidel jako pro dekonstrukční deklaraci.
Jedná se o chybu, pokud positional_pattern vynechá typ, má jeden podpattern bez identifikátoru, nemá žádné property_subpattern a nemá žádné simple_designation. To se nejednoznačným způsobem liší mezi constant_pattern , která je závorka a positional_pattern.
Chcete-li extrahovat hodnoty, které se mají shodovat se vzory v seznamu,
- Pokud je typ vynechán a typ vstupního výrazu je typ řazené kolekce členů, bude počet podpatternů stejný jako kardinalita řazené kolekce členů. Každý prvek řazené kolekce členů se porovná s odpovídajícím podpatternem a shoda bude úspěšná, pokud všechny tyto prvky proběhnou úspěšně. Pokud má některý podpatternidentifikátor, pak tento výraz pojmenuje prvek řazené kolekce členů na odpovídající pozici v typu řazené kolekce členů.
- Jinak, pokud vhodný
Deconstructexistuje jako člen typu, jedná se o chybu v době kompilace, pokud typ vstupní hodnoty není kompatibilní s typem. Za běhu se vstupní hodnota testuje proti typu. Pokud se to nezdaří, shoda pozičního vzoru selže. Pokud bude úspěšné, vstupní hodnota se převede na tento typ aDeconstructvyvolá se s čerstvými proměnnými generovanými kompilátorem pro příjem výstupních parametrů. Každá přijatá hodnota se shoduje s odpovídajícím podpatternem a shoda proběhne úspěšně, pokud jsou všechny tyto hodnoty úspěšné. Pokud má některý dílčí podpatternidentifikátor, pak tento parametr pojmenuje na odpovídající poziciDeconstruct. - V opačném případě, pokud je typ vynechán a vstupní hodnota je typu
objectnebo určitý typ, který lze převéstSystem.ITuplena implicitní převod odkazu, a žádný identifikátor se nezobrazí mezi podpatterny, pak shoda použijeSystem.ITuple. - V opačném případě se jedná o chybu v době kompilace.
Pořadí, ve kterém se podpatterny shodují za běhu, není zadáno a neúspěšná shoda se nemusí pokusit spárovat všechny podpatterny.
Příklad: Tady dekonstruujeme výsledek výrazu a porovnáme výsledné hodnoty s odpovídajícími vnořenými vzory:
static string Classify(Point point) => point switch { (0, 0) => "Origin", (1, 0) => "positive X basis end", (0, 1) => "positive Y basis end", _ => "Just a point", }; public readonly struct Point { public int X { get; } public int Y { get; } public Point(int x, int y) => (X, Y) = (x, y); public void Deconstruct(out int x, out int y) => (x, y) = (X, Y); }konec příkladu
Příklad: Názvy elementů řazené kolekce členů a parametry dekonstrukce lze použít v pozičním vzoru následujícím způsobem:
var numbers = new List<int> { 10, 20, 30 }; if (SumAndCount(numbers) is (Sum: var sum, Count: var count)) { Console.WriteLine($"Sum of [{string.Join(" ", numbers)}] is {sum}"); } static (double Sum, int Count) SumAndCount(IEnumerable<int> numbers) { int sum = 0; int count = 0; foreach (int number in numbers) { sum += number; count++; } return (sum, count); }Výstup je vytvořen.
Sum of [10 20 30] is 60konec příkladu
11.2.6 Vzor vlastností
Property_pattern zkontroluje, že vstupní hodnota není null, a rekurzivně odpovídá hodnotám extrahovaným použitím přístupných vlastností nebo polí.
property_pattern
: type? property_subpattern simple_designation?
;
property_subpattern
: '{' '}'
| '{' subpatterns ','? '}'
;
Jedná se o chybu, pokud některý podpatternproperty_pattern neobsahuje subpattern_name.
Jedná se o chybu v době kompilace, pokud je typ hodnoty null (§8.3.12) nebo odkazový typ s možnou hodnotou null (§8.9.3).
Poznámka: Vzor kontroly hodnoty null se nevyučuje ze vzoru triviální vlastnosti. Pokud chcete zkontrolovat, jestli je řetězec
snenulový, můžete napsat některý z následujících formulářů:#nullable enable string s = "abc"; if (s is object o) ... // o is of type object if (s is string x1) ... // x1 is of type string if (s is {} x2) ... // x2 is of type string if (s is {}) ...koncová poznámka
Vzhledem k tomu, že výraz e odpovídápodpatternům{typu} vzoru, jedná se o chybu v době kompilace, pokud výraz e není kompatibilní se typem T určeným typem. Pokud typ chybí, předpokládá se, že se jedná o statický typ e. Každá subpattern_name , která se objeví na levé straně podpatternů , určí přístupnou čitelnou vlastnost nebo pole T. Pokud existuje simple_designationproperty_pattern , deklaruje proměnnou vzoru typu T.
Za běhu se výraz testuje proti T. Pokud se to nezdaří, vzor vlastnosti se nezdaří a výsledek je false. Pokud je to úspěšné, každé property_subpattern pole nebo vlastnost se přečte a jeho hodnota se shoduje s odpovídajícím vzorem. Výsledek celé shody je false pouze v případě, že výsledek některého z těchto výsledků je false. Pořadí, ve kterém se podpatterny shodují, není zadáno a neúspěšná shoda nemusí testovat všechny podpatterny za běhu. Pokud je shoda úspěšná a simple_designationproperty_pattern je single_variable_designation, deklarovaná proměnná se přiřadí odpovídající hodnotě.
Property_pattern lze použít k porovnávání vzorů s anonymními typy.
Subpattern_name může odkazovat na vnořený člen. V takovém případě je příjemce pro každé vyhledávání jmen typem předchozího člena T₀ počínaje vstupním typemproperty_pattern. Pokud je typ T s možnou hodnotou null, je T₀ jeho základním typem, jinak se T₀ rovná T. Například vzor formuláře { Prop1.Prop2: pattern } je přesně ekvivalentní { Prop1: { Prop2: pattern } }.
Poznámka: Tato možnost bude obsahovat kontrolu hodnoty null, pokud T je typ hodnoty null nebo odkazový typ. Tato kontrola null znamená, že dostupné vnořené vlastnosti budou vlastnosti T₀, ne T. Protože jsou povoleny opakované cesty členů, kompilace porovnávání vzorů může využívat běžné části vzorů. koncová poznámka
Příklad:
var o = ...; if (o is string { Length: 5 } s) ...konec příkladu
Příklad: Kontrola typu za běhu a deklarace proměnné lze přidat do vzoru vlastnosti následujícím způsobem:
Console.WriteLine(TakeFive("Hello, world!")); // output: Hello Console.WriteLine(TakeFive("Hi!")); // output: Hi! Console.WriteLine(TakeFive(new[] { '1', '2', '3', '4', '5', '6', '7' })); // output: 12345 Console.WriteLine(TakeFive(new[] { 'a', 'b', 'c' })); // output: abc static string TakeFive(object input) => input switch { string { Length: >= 5 } s => s.Substring(0, 5), string s => s, ICollection<char> { Count: >= 5 } symbols => new string(symbols.Take(5).ToArray()), ICollection<char> symbols => new string(symbols.ToArray()), null => throw new ArgumentNullException(nameof(input)), _ => throw new ArgumentException("Not supported input type."), };Výstup je vytvořen.
Hello Hi! 12345 abckonec příkladu
11.2.7 Zahodit vzor
Každý výraz odpovídá vzoru zahození, což vede k zahození hodnoty výrazu.
discard_pattern
: '_'
;
Jedná se o chybu v době kompilace použití vzoru zahození v relational_expressionrelational_expression formulářeisnebo jako vzor switch_label.
Poznámka: V těchto případech, aby se shodovaly s libovolným výrazem, použijte var_pattern s zahozením
var _. koncová poznámka
Příklad:
Console.WriteLine(GetDiscountInPercent(DayOfWeek.Friday)); Console.WriteLine(GetDiscountInPercent(null)); Console.WriteLine(GetDiscountInPercent((DayOfWeek)10)); static decimal GetDiscountInPercent(DayOfWeek? dayOfWeek) => dayOfWeek switch { DayOfWeek.Monday => 0.5m, DayOfWeek.Tuesday => 12.5m, DayOfWeek.Wednesday => 7.5m, DayOfWeek.Thursday => 12.5m, DayOfWeek.Friday => 5.0m, DayOfWeek.Saturday => 2.5m, DayOfWeek.Sunday => 2.0m, _ => 0.0m, };Výstup je vytvořen.
5.0 0.0 0.0Zde se vzor zahození používá ke zpracování
nulla jakékoli celočíselné hodnotě, která nemá odpovídající člen výčtuDayOfWeek. To zaručuje, žeswitchvýraz zpracovává všechny možné vstupní hodnoty. konec příkladu
Vzor typu 11.2.8
Type_pattern slouží k otestování, že vstupní hodnota vzoru (§11.1) má daný typ.
type_pattern
: type
;
Pojmenování T typu se vztahuje na každý typ E , pro který E je vzor kompatibilní s T (§11.2.2).
Typ modulu runtime hodnoty je testován proti typu pomocí stejných pravidel zadaných v operátoru is-type (§12.15.12.1). Pokud je test úspěšný, vzor odpovídá této hodnotě. Jedná se o chybu v době kompilace, pokud je typ typu s možnou hodnotou null. Tento vzorový formulář nikdy neodpovídá hodnotě null .
11.2.9 Relační vzor
Relational_pattern slouží k relačnímu testování vstupní hodnoty vzoru (§11.1) proti konstantní hodnotě.
relational_pattern
: '<' relational_expression
| '<=' relational_expression
| '>' relational_expression
| '>=' relational_expression
;
Relational_expression v relational_pattern se vyžaduje k vyhodnocení na konstantní hodnotu.
Relační vzorce podporují relační operátory <, <=, , >a >= na všech předdefinovaných typech, které podporují tyto binární relační operátory s oběma operandy se stejným typem: sbyte, byte, shortushort, , int, uint, longulongcharfloatdoubledecimalnintnuinta výčty.
Relational_pattern se vztahuje na typT, pokud je vhodný integrovaný binární relační operátor definován s oběma operandy typu T, nebo pokud explicitní převod nullable nebo unboxing existuje od T typu konstantního výrazu.
Jedná se o chybu v době kompilace, pokud se výraz vyhodnotí jako double.NaN, float.NaNnebo null konstanta.
Pokud má vstupní hodnota typ, pro který je definován vhodný předdefinovaný binární relační operátor, vyhodnocení tohoto operátoru se považuje za význam relačního vzoru. V opačném případě se vstupní hodnota převede na typ konstantního výrazu pomocí explicitního převodu s možnou hodnotou null nebo rozbalení. Jedná se o chybu v době kompilace, pokud neexistuje žádný takový převod. Model se považuje za nekohodný, pokud převod selže. Pokud převod proběhne úspěšně, výsledkem operace porovnávání vzorů je výsledek vyhodnocení výrazu e «op» v , kde e je převedený vstup, «op» je relační operátor a v je konstantní výraz.
Příklad:
Console.WriteLine(Classify(13)); Console.WriteLine(Classify(double.NaN)); Console.WriteLine(Classify(2.4)); static string Classify(double measurement) => measurement switch { < -4.0 => "Too low", > 10.0 => "Too high", double.NaN => "Unknown", _ => "Acceptable", };Výstup je vytvořen.
Too high Unknown Acceptablekonec příkladu
11.2.10 Logický vzor
Logical_pattern slouží k negování výsledku shody vzorku nebo ke kombinování výsledků více shod vzorů pomocí spojení (and) nebo disjunkce (or).
logical_pattern
: disjunctive_pattern
;
disjunctive_pattern
: disjunctive_pattern 'or' conjunctive_pattern
| conjunctive_pattern
;
conjunctive_pattern
: conjunctive_pattern 'and' negated_pattern
| negated_pattern
;
negated_pattern
: 'not' negated_pattern
| primary_pattern
;
not, anda or jsou souhrnně označovány jako operátory vzorů.
Negated_pattern odpovídá, pokud se vzor negovaný neshoduje a naopak.
Conjunctive_pattern vyžaduje, aby se oba vzory shodovaly.
Disjunctive_pattern vyžaduje, aby se shodovaly oba vzory. Na rozdíl od jejich jazykových operátorů a a &&|| operátory andor zkratování.
Jedná se o chybu v době kompilace pro deklarování proměnné vzoru pod operátorem nebo not operátorem or vzoru.
Poznámka: Protože ani nemůže
notorvytvořit určité přiřazení pro proměnnou vzoru, jedná se o chybu deklarování jedné z těchto pozic. koncová poznámka
V conjunctive_pattern je vstupní typ druhého vzoru zúžen požadavky na zúžení typu prvního vzoru and.
Zúžený typ vzoru P je definován takto:
- Pokud
Pje vzor typu, zúžený typ je typ vzoru typu. - V opačném případě, pokud
Pje vzor deklarace, zúžený typ je typ modelu deklarace. - V opačném případě, pokud
Pje rekurzivní vzor, který dává explicitní typ, zúžený typ je tento typ. - V opačném případě je-li
Pshodován pomocí pravidel proITuplepositional_pattern (§11.2.5), je zúžený typ typuSystem.ITuple. - Jinak je-li
Pkonstantní vzor, kde konstanta není nulová konstanta a kde výraz nemá žádný konstantní převod výrazu na vstupní typ, zúžený typ je typ konstanty. - V opačném případě je-li
Prelační vzor, kde konstantní výraz nemá žádný konstantní výraz převod na vstupní typ, zúžený typ je typ konstanty. - V opačném případě, pokud
Pjeorvzor, je zúžený typzúžený typ podpatternů, pokud takový společný typ existuje. Pro tento účel algoritmus běžného typu bere v úvahu pouze převody identity, boxingu a implicitního odkazu a bere v úvahu všechny podpatterny posloupnostiorvzorů (ignoruje závorky). - V opačném případě, pokud
Pjeandvzor, zúžený typ je zúžený typ správného vzoru. Zúžený typ levého vzorku je navíc vstupním typem pravého vzoru. - V opačném případě je zúžený typ vstupního
PPtypu.
Poznámka: Jak je uvedeno gramatikou,
notmá přednost předand, který má přednost předor. To může být explicitně označeno nebo přepsáno pomocí závorek. koncová poznámka
Když se vzor objeví na pravé straně is, rozsah vzoru je určen gramatikou; v důsledku toho operátory andvzoru , ora not v rámci vzoru svázat těsněji než logické operátory &&, ||a ! mimo vzor.
Příklad:
Console.WriteLine(Classify(13)); Console.WriteLine(Classify(-100)); Console.WriteLine(Classify(5.7)); static string Classify(double measurement) => measurement switch { < -40.0 => "Too low", >= -40.0 and < 0 => "Low", >= 0 and < 10.0 => "Acceptable", >= 10.0 and < 20.0 => "High", >= 20.0 => "Too high", double.NaN => "Unknown", };Výstup je vytvořen.
High Too low Acceptablekonec příkladu
Příklad:
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 1, 19))); Console.WriteLine(GetCalendarSeason(new DateTime(2021, 10, 9))); Console.WriteLine(GetCalendarSeason(new DateTime(2021, 5, 11))); static string GetCalendarSeason(DateTime date) => date.Month switch { 3 or 4 or 5 => "spring", 6 or 7 or 8 => "summer", 9 or 10 or 11 => "autumn", 12 or 1 or 2 => "winter", _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."), };Výstup je vytvořen.
winter autumn springkonec příkladu
Příklad:
object msg = "msg"; object obj = 5; bool flag = true; // This is parsed as: (msg is (not int) or string) result = msg is not int or string; Console.WriteLine($"msg (\"msg\"): msg is not int or string: {result}"); // This is parsed as: (obj is (int or string)) && flag bool result = obj is int or string && flag; Console.WriteLine($"obj (5), flag (true): obj is int or string && flag: {result}"); // This is parsed as: (obj is int) || ((obj is string) && flag) result = obj is int || obj is string && flag; Console.WriteLine($"obj (5), flag (true): obj is int || obj is string && flag: {result}"); flag = false; // This is parsed as: (obj is (int or string)) && flag result = obj is int or string && flag; Console.WriteLine($"obj (5), flag (false): obj is int or string && flag: {result}"); // This is parsed as: (obj is int) || ((obj is string) && flag) result = obj is int || obj is string && flag; Console.WriteLine($"obj (5), flag (false): obj is int || obj is string && flag: {result}");Výstup je vytvořen.
msg ("msg"): msg is not int or string: True obj (5), flag (true): obj is int or string && flag: True obj (5), flag (true): obj is int || obj is string && flag: True obj (5), flag (false): obj is int or string && flag: False obj (5), flag (false): obj is int || obj is string && flag: Truekonec příkladu
11.3 Dílčí podsumpce vzorku
V příkazu switch se jedná o chybu, pokud je vzor případu podsoučet předchozí sadou nehlídaných případů (§13.8.3). Neformálně to znamená, že jakákoli vstupní hodnota by se shodovala s jednou z předchozích případů. Následující pravidla definují, kdy sada vzorů podsoustaví daný vzor:
Vzor Pby se shodoval s konstantou K v případě, že se uchovávají některé z následujících podmínek:
- specifikace chování modulu runtime daného vzoru odpovídá
PK. -
Pje type_pattern pro typTaKnenínulla typ modulu runtimeKjeTnebo typ odvozený zTnebo typ, který implementujeT. -
Pje relational_pattern s operátorem «op» a konstantouv, a výrazK«op»vby byl vyhodnocen jakotrue. -
Pje negated_patternnot P₁aP₁neodpovídáK. -
Pje conjunctive_patternP₁ and P₂a obaP₁by odpovídalyKaP₂odpovídalyK. -
Pje disjunctive_patternP₁ or P₂a buďP₁by se shodovalK, neboP₂by odpovídalK. -
Pje discard_pattern.
Sada vzorů Qpodsoustaví vzor P , pokud se drží některé z následujících podmínek:
-
Pje konstantní vzor a libovolný ze vzorů v saděQby odpovídalPpřevedené hodnotě. -
Pje vzor var a sada vzorů je vyčerpávající (§11.4) pro typ vstupní hodnoty vzoru (Q) a buď vstupní hodnota vzoru není typu null, nebo by se shodoval nějaký vzor.Qnull -
Pje vzor deklarace s typemTa sada vzorůQje vyčerpávající pro typT(§11.4). -
Pje type_pattern pro typTa sada vzorůQje pro typTvyčerpávající . -
Pje relational_pattern s operátorem «op» a konstantní hodnotouv, a pro každou hodnotu vstupního typu vyhovující relační «op»v, určitý vzor v saděQby odpovídal této hodnotě. -
Pje disjunctive_patternP₁ or P₂a sada dílčích vzorůQP₁aQdílčích motivůP₂. -
Pje conjunctive_patternP₁ and P₂a alespoň jeden z následujících blokování:QsubsumesP₁, neboQsubsumesP₂. -
Pje negated_patternnot P₁aQje vyčerpávající pro vstupní typ s ohledem pouze na hodnoty, kteréP₁neodpovídají . -
Pje discard_pattern a sada vzorůQje vyčerpávající pro typ vstupní hodnoty vzoru, a buď vstupní hodnota vzoru není typu s možnou hodnotou null, nebo nějaký vzor byQodpovídalnull. - Nějaký vzor
Qje disjunctive_patternQ₁ or Q₂a nahrazením daného vzoruQ₁Qby přineslo sadu, která se podsoučtyP, nebo nahrazeníQ₂by přinesla sadu, která se podsoubíP. - Určitý vzor
Qje negated_patternnot Q₁aPneodpovídá žádné hodnotě, kteráQ₁by se shodovala.
11.4 Úplnost vzoru
Neformálně je sada vzorů pro typ vyčerpávající, pokud platí pro každou možnou hodnotu tohoto typu kromě hodnoty null, je možné použít nějaký vzor v sadě. Následující pravidla definují, kdy je sada vzorů pro typ vyčerpávající :
Sada vzorů Q je , pokud jsou splněny některé z následujících podmínek:
-
Tje celočíselný nebo výčtový typ nebo verze jednoho z nich s možnou hodnotou null a pro každou možnou hodnotu základníhoTtypu, kteráQnení nullable, by se určitý vzor shodoval s danou hodnotou; - Určitý vzor v
Qje var vzor; nebo - Určitý vzor je
Qvzor deklarace pro typDa existuje převod identity, implicitní převod odkazu nebo boxing převodu zTD; nebo - Určitý vzor
Qje type_pattern pro typDa existuje převod identity, implicitní převod odkazu nebo boxing převod zTD; nebo - Určitý vzor je
Qdiscard_pattern; nebo - Vzory
Qzahrnují kombinaci relational_patterns a constant_patterns, jejichž rozsahy souhrnně pokrývají všechny možné hodnoty základníhoTtypu bez hodnoty null. Ufloatadoubletypech to zahrnujeSystem.Double.NaNneboSystem.Single.NaNv uvedeném pořadí, protožeNaNse neshoduje s žádným relačním vzorem; nebo - Určitý vzor
Qje disjunctive_patternP₁ or P₂a nahrazením daného vzoruP₁oběma aP₂vyneseQsadu, která je vyčerpávající proT; nebo - Určitý vzor v
Qje negated_patternnot P₁a vzory společněQs hodnotami, které nejsou spároványP₁pokrytím všech možných hodnotT. Negated_patternnot P₁je sám o sobě vyčerpávající, pokudP₁neodpovídá žádné možné hodnotěT; nebo - V některých vzorech
Qje conjunctive_patternP₁ and P₂a sada obsahující pouzeP₁je vyčerpávajícíTa sada obsahující pouzeP₂je vyčerpávající proT.
Poznámka: Pokud vzor typu obsahuje typy s možnou hodnotou null, může být vzor pro typ vyčerpávající, ale přesto vygeneruje upozornění, protože vzor typu neodpovídá hodnotě
null. koncová poznámka
Poznámka: U typů s plovoucí desetinou čárkou není kombinace vzorů
< 0a>= 0není vyčerpávající, protože relační vzor neodpovídáNaN. Správná vyčerpávající sada by byla< 0,>= 0adouble.NaN(nebofloat.NaN). koncová poznámka
Příklad:
static void M(byte b) { switch (b) { case 0: case 1: case 2: ... // handle every specific value of byte break; // error: the pattern 'byte other' is subsumed by the (exhaustive) // previous cases case byte other: break; } }konec příkladu
ECMA C# draft specification