11 Desen ve desen eşleştirme

11.1 Genel

Desen, işleçle is (§12.15.12), switch_statement (§13.8.3) ve switch_expression (§12.12) ile birlikte gelen verilerin karşılaştırılacağı veri şeklini ifade etmek için kullanılabilen söz dizimsel bir formdur. Desenler özyinelemeli olabilir, böylece verilerin bölümleri alt desenlerle eşleştirilebilir.

Desen, çeşitli bağlamlardaki bir değere göre test edilir:

  • Switch deyiminde, bir servis talebi etiketinin deseni switch deyiminin ifadesinde test edilir.
  • bir is-pattern işlecinde, sağ taraftaki desen soldaki ifadeye göre test edilir.
  • Switch ifadesinde, switch_expression_armdeseni switch-expression'ın sol tarafındaki ifadeye göre test edilir.
  • İç içe bağlamlarda alt desen, desen formuna bağlı olarak özelliklerden, alanlardan alınan veya diğer giriş değerlerinden dizine alınan değerlerle test edilir.

Bir desenin sınandığı değer, desen giriş değeri olarak adlandırılır.

11.2 Desen formları

11.2.1 Genel

Bir desen aşağıdaki formlardan birine sahip olabilir:

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 ')'
    ;

Üretim, '(' pattern ')' logical_pattern birini kullanarak birleştirilen desenler arasında değerlendirme sırasını zorlamak için desenin paranteziçine alınmasına olanak tanır.

Bazı desenleryerel bir değişkenin bildirimiyle sonuçlanabilir.

Her desen formu, desenin uygulanabileceği giriş değerleri için tür kümesini tanımlar. Desen, değerleri P eşleşebilecek türler arasındaysa, T bir tür için geçerlidirT Için geçerli değilse P , bir programda desen giriş değeriyle (§11.1) T eşleşecek şekilde görüntüleniyorsa P derleme zamanı hatasıdır T.

Örnek: Aşağıdaki örnek, derleme zamanı türü v olduğundan TextReaderderleme zamanı hatası oluşturur. Türündeki TextReader bir değişkenin hiçbir zaman ile stringbaşvuru uyumlu bir değeri olamaz:

TextReader v = Console.In; // compile-time type of 'v' is 'TextReader'
if (v is string) // compile-time error
{
    // code assuming v is a string
}

Ancak, aşağıdaki derleme zamanı türü v olduğundan objectderleme zamanı hatası oluşturmaz. Türünde object bir değişken, ile stringbaşvuru uyumlu bir değere sahip olabilir:

object v = Console.In;
if (v is string s)
{
    // code assuming v is a string
}

son örnek

Her desen formu, desenin çalışma zamanındaki değerle eşleşdiği değer kümesini tanımlar.

Desen eşleştirme sırasında işlemlerin ve yan etkilerin değerlendirilmesi sırası ( Deconstructiçindeki yöntemlerin System.ITupleçağrıları, özellik erişimleri ve çağrıları) belirtilmez.

11.2.2 Bildirim düzeni

declaration_pattern, bir değerin belirli bir türe sahip olup olmadığını test etmek ve test başarılı olursa isteğe bağlı olarak bu türdeki bir değişkende değer sağlamak için kullanılır.

declaration_pattern
    : type simple_designation
    ;
simple_designation
    : discard_designation
    | single_variable_designation
    ;
discard_designation
    : '_'
    ;
single_variable_designation
    : identifier
    ;

Belirteci olan _, single_variable_designation yerine discard_designation olarak kabul edilir.

Değerin çalışma zamanı türü, is-type işlecinde (§12.15.12.1) belirtilen kurallar kullanılarak desendeki türe göre test edilir. Test başarılı olursa, desen bu değerle eşleşir . Tür null atanabilir bir değer türü (§8.3.12) veya null atanabilir başvuru türü (§8.9.3) ise derleme zamanı hatasıdır. Bu desen formu hiçbir zaman bir değerle null eşleşmez.

Not: is-type ifadesi e is T ve bildirim deseni e is T _ null atanabilir bir tür olmadığında eşdeğerdir T . son not

Bir desen giriş değeri (§11.1) e verildiğinde, simple_designationdiscard_designation ise atma (§9.2.9.2) değerini belirtir ve e değeri hiçbir şeye bağlı değildir. (Bu noktada adıyla _ bildirilen bir değişken kapsam içinde olsa da, bu adlandırılmış değişken bu bağlamda görülmez.) Aksi takdirde , simple_designationsingle_variable_designation, verilen tanımlayıcı tarafından adlandırılan belirtilen türde bir yerel değişken (§9.2.9) kullanıma sunulur. Bu yerel değişkene, desen değerle eşleştiğinde desen giriş değerinin değeri atanır.

Desen giriş değerinin statik türünün ve verilen türün belirli birleşimleri uyumsuz olarak kabul edilir ve derleme zamanı hatasına neden olur. Statik türdeki E bir değerin, bir kimlik dönüştürmesi, örtük veya açık başvuru dönüştürmesi, kutulama dönüştürmesi, gelen kutusu açma dönüştürmesi veya 'den örtük veya açık null atanabilir değer türü dönüştürmesi varsa veya açık bir türse TE (T) türüyle E uyumlu desenle T olduğu söylenir. Bir türü T adlandıran bildirim deseni, geçerlidir.

Not: Açık türler için destek en çok yapı veya sınıf türleri olabilecek türleri denetlerken yararlı olabilir ve kutulamadan kaçınılmalıdır. son not

Örnek: Bildirim deseni, başvuru türlerinin çalışma zamanı türü testlerini gerçekleştirmek için kullanışlıdır ve deyiminin yerini alır

var v = expr as Type;
if (v != null) { /* code using v */ }

biraz daha kısa

if (expr is Type v) { /* code using v */ }

son örnek

Örnek: Bildirim deseni, null atanabilir türlerin değerlerini test etmek için kullanılabilir: değer null olmayan ve Nullable<T>Tise tür deseni T2 id (veya kutuluT2) bir tür deseni T ile eşleşir ya da bazı temel türü veya arabirimi.T Örneğin, kod parçasında

int? x = 3;
if (x is int v) { /* code using v */ }

deyiminin if koşulu çalışma zamanındadır true ve değişkenv, bloğun içindeki türün 3 değerini int tutar. Blok sonrasında değişken v kapsam içindedir, ancak kesinlikle atanmamış olur. son örnek

11.2.3 Sabit deseni

Bir desen giriş değerinin (§11.1) değerini verilen sabit değerle test etmek için bir constant_pattern kullanılır.

constant_pattern
    : constant_expression
    ;

sabit ifadesinden türüne PT geçerlidir.P

Sabit bir desen içinP, dönüştürülen değeri

  • Desen giriş değerinin türü bir tamsayı türü veya bir numaralandırma türüyse, desenin sabit değeri bu türe dönüştürülür; yoksa
  • Desen giriş değerinin türü bir tamsayı türünün veya bir sabit sabit türünün null atanabilir sürümüyse, desenin sabit değeri temel alınan türüne dönüştürülür; yoksa
  • desenin sabit değerinin değeri.

Esahip sabit bir desen P verildiğinde,

  • e tamsayı türüne veya sabit listesi türüne veya bunlardan birinin null atanabilir bir biçimine ve v tamsayı türüne sahipse, ifadenin P sonucu ise desen ; aksi takdirde
  • deseni P.

Örnek: switch Aşağıdaki yöntemdeki deyimi, büyük/küçük harf etiketlerinde beş sabit desen kullanır.

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(...);
    }
}

son örnek

11.2.4 Var deseni

var_pattern her değerle eşleşir. Başka bir ifadeyle, var_pattern ile desen eşleştirme işlemi her zaman başarılı olur.

var_pattern her tür için geçerlidir.

var_pattern
    : 'var' designation
    ;
designation
    : simple_designation
    | tuple_designation
    ;
tuple_designation
    : '(' designations? ')'
    ;
designations
    : designation (',' designation)*
    ;

Bir desen giriş değeri (§11.1) e verildiğinde, atamadiscard_designation ise atılan değeri (§9.2.9.2) belirtir ve e değeri hiçbir şeye bağlı değildir. (Bu ada sahip bildirilen bir değişken bu noktada kapsam içinde olsa da, bu adlandırılmış değişken bu bağlamda görülmez.) Aksi takdirde, atamasingle_variable_designation ise çalışma zamanında e değeri, türü statik e türü olan ve desen giriş değeri bu yerel değişkene atanmış olan bu adın yeni tanıtılan yerel değişkenine (§9.2.9) bağlıdır.

Advar, bir var_pattern kullanıldığı bir türe bağlanacaksa bu bir hatadır.

Atama bir tuple_designation ise, desen form gösteriminin(var (§11.2.5) eşdeğerdir, ... )burada, tuple_designation içinde bulunanlar olarak ifadeedilir. Örneğin, desen var (x, (y, z)) ile (var x, (var y, var z))eşdeğerdir.

11.2.5 Konumsal desen

positional_pattern giriş değerinin olmadığını nulldenetler, uygun Deconstruct bir yöntem (§12.7) çağırır ve sonuçta elde edilen değerlerde daha fazla desen eşleştirmesi gerçekleştirir. Ayrıca, giriş değerinin türü öğesini içeren Deconstructtürle aynı olduğunda veya giriş değerinin türü bir tanımlama grubu türündeyse veya giriş object değerinin türü veya System.ITuple ise ve ifadenin çalışma zamanı türü uygulandığında System.ITupletanımlama grubu benzeri bir desen söz dizimini (sağlanan tür olmadan) destekler.

positional_pattern
    : type? '(' subpatterns? ')' property_subpattern? simple_designation?
    ;
subpatterns
    : subpattern (',' subpattern)*
    ;
subpattern
    : pattern
    | subpattern_name ':' pattern
    ;
subpattern_name
    : identifier
    | subpattern_name '.' identifier
    ;

Bir giriş değerinin desen türü(alt desenleriyle) eşleşmesi göz önüne alındığında, türü içinde erişilebilir bildirimleri Deconstruct ve bunlar arasında, yapısızlaştırma bildirimiyle aynı kurallar kullanılarak bir yöntem seçilir. Bir positional_pattern türü atlarsa, tanımlayıcısı olmayan tek bir alt sayfaya sahipse, property_subpattern yoksa ve simple_designation yoksa hatadır. Bu, parantez içindeki bir constant_pattern ile positional_pattern arasında ayrımlar. Listedeki desenlerle eşleşecek değerleri ayıklamak için,

  • Tür atlanırsa ve giriş ifadesinin türü bir tanımlama grubu türüyse, alt ekran sayısı tanımlama grubunun kardinalitesi ile aynı olmalıdır. Her tanımlama grubu öğesi karşılık gelen alt çizgiyle eşleştirilir ve bunların tümü başarılı olursa eşleşme başarılı olur. Herhangi bir alt çizginintanımlayıcısı varsa, bu, tanımlama grubu türündeki karşılık gelen konumda bir tanımlama grubu öğesini adlandıracaktır.
  • Aksi takdirde, uygun Deconstruct bir türün üyesi olarak varsa, giriş değerinin türü türle desen uyumlu değilse derleme zamanı hatasıdır. Çalışma zamanında giriş değeri türe göre test edilir. Bu başarısız olursa, konumsal desen eşleşmesi başarısız olur. Başarılı olursa, giriş değeri bu türe dönüştürülür ve Deconstruct çıkış parametrelerini almak için derleyici tarafından oluşturulan yeni değişkenlerle çağrılır. Alınan her değer ilgili alt çizgiyle eşleştirilir ve bunların tümü başarılı olursa eşleşme başarılı olur. Herhangi bir alt belgenintanımlayıcısı varsa, bu, ilgili konumundaki bir parametreyi Deconstructadlandıracaktır.
  • Aksi takdirde, tür atlanırsa ve giriş değeri object türü veya örtük başvuru dönüştürmesi tarafından dönüştürülebilecek System.ITuple bir tür ise ve alt grafikler arasında hiçbir tanımlayıcı görünmezse, eşleşme kullanır System.ITuple.
  • Aksi takdirde, desen bir derleme zamanı hatasıdır.

Çalışma zamanında alt grafiklerin eşleşme sırası belirtilmemiştir ve başarısız bir eşleşme tüm alt grafiklerle eşleşmeye çalışmayabilir.

Örnek: Burada, bir ifade sonucunun yapısını kaldıracak ve sonuçta elde edilen değerleri ilgili iç içe yerleştirilmiş desenlerle eşleştireceğiz:

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);
}

son örnek

Örnek: Tanımlama grubu öğelerinin ve Deconstruct parametrelerinin adları aşağıdaki gibi konumsal bir düzende kullanılabilir:

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);
}

Üretilen çıkış şu şekildedir:

Sum of [10 20 30] is 60

son örnek

11.2.6 Özellik düzeni

property_pattern, giriş değerinin olup olmadığını nulldenetler ve erişilebilir özelliklerin veya alanların kullanımıyla ayıklanan değerlerle özyinelemeli olarak eşleşir.

property_pattern
    : type? property_subpattern simple_designation?
    ;
property_subpattern
    : '{' '}'
    | '{' subpatterns ','? '}'
    ;

Bir property_patternalt boyası subpattern_name içermiyorsa bu bir hatadır.

Tür null atanabilir bir değer türü (§8.3.12) veya null atanabilir başvuru türü (§8.9.3) ise derleme zamanı hatasıdır.

Not: Null denetim deseni önemsiz bir özellik deseninin dışında kalır. Dizenin s null olmadığını denetlemek için aşağıdaki formlardan herhangi birini yazabilirsiniz:

#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 {}) ...

son not

E ifadesinin desen türü{alt desenleriyle} eşleşmesi göz önüne alındığında, e ifadesi türe göre belirlenenT türüyle desen uyumlu değilse derleme zamanı hatası olur. Tür yoksa, türün statik e türü olduğu varsayılır. Alt yazılarının sol tarafında görünen her subpattern_name erişilebilir bir okunabilir özellik veya T alanı belirlemesi gerekir. property_pattern simple_designation varsa, T türünde bir desen değişkeni bildirir.

Çalışma zamanında ifade T'ye karşı test edilir. Bu başarısız olursa özellik deseni eşleşmesi başarısız olur ve sonuç olur false. Başarılı olursa, her property_subpattern alanı veya özelliği okunur ve değeri ilgili desenle eşleştirilir. Tüm eşleşmenin false sonucu yalnızca bunlardan herhangi birinin sonucu ise olur false. Alt yordamların eşleştirilme sırası belirtilmez ve başarısız bir eşleşme çalışma zamanında tüm alt yordamları test etmeyebilir. Eşleşme başarılı olursa ve property_pattern simple_designation bir single_variable_designation ise, bildirilen değişkene eşleşen değer atanır.

property_pattern, anonim türlerle desen eşleştirmek için kullanılabilir.

bir subpattern_name iç içe üyeye başvurabilir. Böyle bir durumda, her ad araması için alıcı, property_patterngiriş türünden başlayarak önceki T₀ üyesinin türüdür. T null atanabilir bir türse, T₀ onun temel türüdür, aksi takdirde T₀T'ye eşittir. Örneğin, formun { Prop1.Prop2: pattern } deseni tam olarak ile { Prop1: { Prop2: pattern } }eşdeğerdir.

Not: Bu, T null atanabilir bir değer türü veya başvuru türü olduğunda null denetimi içerir. Bu null denetim, kullanılabilir iç içe özelliklerin T'nin değil T₀'nin özellikleri olacağı anlamına gelir. Yinelenen üye yollarına izin verildiğinden, desen eşleştirmenin derlenmesi desenlerin ortak bölümlerinden yararlanabilir. son not

Örnek:

var o = ...;
if (o is string { Length: 5 } s) ...

son örnek

Örnek: Aşağıdaki gibi, bir çalışma zamanı türü denetimi ve bir değişken bildirimi bir özellik desenine eklenebilir:

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."),
};

Üretilen çıkış şu şekildedir:

Hello
Hi!
12345
abc

son örnek

11.2.7 Atma düzeni

Her ifade atma deseni ile eşleşir ve bu da ifadenin değerinin atılmasıyla sonuçlanır.

discard_pattern
    : '_'
    ;

Form relational_expression deseninin relational_expression atma deseninin kullanılması veya switch_labelisdeseni olarak kullanılması derleme zamanı hatasıdır.

Not: Bu gibi durumlarda, herhangi bir ifadeyi eşleştirmek için at ile var _ kullanın. son not

Örnek:

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,
};

Üretilen çıkış şu şekildedir:

5.0
0.0
0.0

Burada, numaralandırmanın karşılık gelen üyesine sahip olmayan herhangi bir tamsayı değerini işlemek null için bir atma deseni DayOfWeek kullanılır. Bu, ifadenin tüm olası giriş değerlerini işlemesini switch garanti eder. son örnek

11.2.8 Tür deseni

Type_pattern, desen giriş değerinin (§11.1) belirli bir türe sahip olduğunu test etmek için kullanılır.

type_pattern
    : type
    ;

Türü adlandıran bir tür T deseni, deseni (§11.2.2) ile Tuyumlu olan E her tür E için geçerlidir.

Değerin çalışma zamanı türü , is-type işlecinde (§12.15.12.1) belirtilen kurallar kullanılarak türe göre test edilir. Test başarılı olursa, desen bu değerle eşleşir. Tür null atanabilir bir türse derleme zamanı hatasıdır. Bu desen formu hiçbir zaman bir değerle null eşleşmez.

11.2.9 İlişkisel desen

relational_pattern, desen giriş değerini (§11.1) sabit bir değerle ilişkisel olarak test etmek için kullanılır.

relational_pattern
    : '<'  relational_expression
    | '<=' relational_expression
    | '>'  relational_expression
    | '>=' relational_expression
    ;

Sabit bir değere değerlendirmek için bir relational_pattern içindeki relational_expression gereklidir.

İlişkisel desenler, <<=> her iki işlenenin de aynı türe sahip olduğu ikili ilişkisel işleçleri destekleyen tüm yerleşik türler üzerinde , , ve ilişkisel işleçleri >=destekler: sbyte, byte, shortushort, , int, uint, longulongcharfloatdoubledecimalnintnuintve sabit listeleri.

türündeki her iki işlenenle de uygun bir yerleşik ikili ilişkisel işleç tanımlanmışsa veya sabit ifadenin türüne açık bir null atanabilir veya kutulanmamış dönüştürme varsaT, relational_pattern bir tür için TT.

İfade , double.NaNveya null sabit olarak değerlendirilirse float.NaNbu bir derleme zamanı hatasıdır.

Giriş değeri, uygun bir yerleşik ikili ilişkisel işlecin tanımlandığı bir türe sahip olduğunda, bu işlecin değerlendirilmesi ilişkisel desenin anlamı olarak alınır. Aksi takdirde, giriş değeri açık bir null atanabilir veya kutulanmamış dönüştürme kullanılarak sabit ifade türüne dönüştürülür. Böyle bir dönüştürme yoksa bu bir derleme zamanı hatasıdır. Dönüştürme başarısız olursa desenin eşleşmediği kabul edilir. Dönüştürme başarılı olursa, desen eşleştirme işleminin sonucu, dönüştürülen girişin ifadenin e «op» v değerlendirilmesinin e sonucudur; «op» ilişkisel işleç ve v sabit ifadedir.

Örnek:

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",
};

Üretilen çıkış şu şekildedir:

Too high
Unknown
Acceptable

son örnek

11.2.10 Mantıksal desen

logical_pattern, bir desen eşleşmesinin sonucunu yok etmek veya bağlaç () veya ayrıştırma (andor) kullanarak birden çok desen eşleşmesinin sonuçlarını birleştirmek için kullanılır.

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, andve or topluca desen işleçleri olarak adlandırılır.

Negated_pattern, olumsuzlanan desen eşleşmiyorsa eşleşir ve tam tersi de geçerlidir. bir conjunctive_pattern her iki desenin de eşleşmesini gerektirir. disjunctive_pattern eşleşmesi için iki desen gerekir. Dil işleci karşılıklarının && aksine ve ||andor kısa devre işleçleri değildir.

Bir desen değişkeninin veya not desen işleci altında bildirilmesi derleme or zamanı hatasıdır.

Not: Bir notor desen değişkeni için kesin atama üretemediği veya üretemediği için, bu konumlarda bir tane bildirmek bir hatadır. son not

conjunctive_pattern ikinci desenin giriş türü, ilk deseninin and. Bir desenin P aşağıdaki gibi tanımlanır:

  • Tür deseni ise P , daraltılmış tür , tür deseninin türünün türüdür.
  • Aksi takdirde, bir bildirim deseni ise P , daraltılmış tür bildirim deseninin türünün türüdür.
  • Aksi takdirde, açık bir tür veren özyinelemeli bir desense P , daraltılmış tür bu türdür.
  • Aksi takdirde, bir positional_pattern (§11.2.5) içindeki kurallarıyla ITuple eşleştirilirse P, daraltılmış tür türüdürSystem.ITuple.
  • Aksi takdirde, sabitin null sabit olmadığı ve ifadenin Psabit ifade dönüştürmesinin olmadığı sabit bir desense, daraltılmış tür sabitin türüdür.
  • Aksi takdirde, sabit ifadenin Psabit ifade dönüştürmesinin olmadığı ilişkisel bir desense, daraltılmış tür sabitin türüdür.
  • Aksi takdirde, bir P desen iseor, daraltılmış tür, böyle bir ortak tür varsa, daraltılmış alt ekran türlerinin ortak türüdür. Bu amaçla, ortak tür algoritması yalnızca kimlik, kutulama ve örtük başvuru dönüştürmelerini dikkate alır ve bir desen dizisinin or tüm alt desenlerini (parantezli desenleri yoksayarak) dikkate alır.
  • Aksi takdirde, bir P desen iseand, dar türü doğru desenin daraltılmış türüdür. Ayrıca, sol desenin dar türü , sağ desenin giriş türüdür .
  • Aksi takdirde daraltılmış türüPP' nin giriş türüdür.

Not: Dil bilgisi tarafından belirtildiği gibi, not üzerinde önceliği andvardır ve bu öncelik üzerindedir or. Bu, parantezler kullanılarak açıkça gösterilebilir veya geçersiz kılınabilir. son not

sağ tarafında bir is göründüğünde, desenin kapsamı dil bilgisi tarafından belirlenir; sonuç olarak desen işleçleri , andve or desen içindeki desen işleçleri not, &&ve || desenin dışında mantıksal işleçlere !göre daha sıkı bağlanır.

Örnek:

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",
};

Üretilen çıkış şu şekildedir:

High
Too low
Acceptable

son örnek

Örnek:

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}."),
};

Üretilen çıkış şu şekildedir:

winter
autumn
spring

son örnek

Örnek:

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}");

Üretilen çıkış şu şekildedir:

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: True

son örnek

11.3 Desen alt devamı

Switch deyiminde, bir servis talebinin deseninin önceki korumasız vaka kümesi (§13.8.3) tarafından çıkarılması hatadır. Bu, herhangi bir giriş değerinin önceki durumlardan biriyle eşleştirildiği anlamına gelir. Aşağıdaki kurallar, bir desen kümesinin belirli bir desenin ne zaman alt toplamını verdiğini tanımlar:

Aşağıdaki koşullardan herhangi biri tutarsa bir desen P sabitle K:

  • bu desenin çalışma zamanı davranışının P belirtimi ile eşleşen Kbelirtimdir.
  • Ptürü için bir T ve K değil null ve çalışma zamanı türü K ya da türünden T türetilen bir tür ya da uygulayan Tbir türdürT.
  • Pişleci «op» ve sabit olan bir v ve «op» K ifadesi v olarak değerlendirilirtrue.
  • P bir negated_patternnot P₁ ve P₁ ile eşleşmiyor K.
  • P bir conjunctive_patternP₁ and P₂ ve her ikisi de P₁ eşleşip KP₂ eşleşeceğini Kgösterir.
  • Pbir disjunctive_patternP₁ or P₂ ve ya eşleştirilir P₁ ya da KP₂ eşleşerK.
  • P bir discard_pattern.

Bir dizi desen Q dizinini oluşturur:

  • Psabit bir desendir ve kümedeki Q desenlerden herhangi biri P eşleşir
  • Pbir var desenidir ve desen Q kümesi desen giriş değerinin türü (§11.1) için kapsamlıdır
  • Ptürüne T sahip bir bildirim desenidir ve desen Q kümesi tür için kapsamlıdır T (§11.4).
  • Ptürü için bir T ve desen Q kümesi türü için T.
  • P« op» işleci ve sabit değeri olan bir v ve «op» vilişkisini karşılayan giriş türünün her değeri için, kümedeki Q bazı desenler bu değerle eşleşir.
  • P bir disjunctive_patternP₁ or P₂ ve desen Q alt toplamları P₁ ve Q alt dizileri kümesidir P₂.
  • P bir conjunctive_patternP₁ and P₂ ve aşağıdakilerden en az birini tutar: Q alt toplamlar P₁veya Q alt toplamlar P₂.
  • Pbir negated_patternnot P₁ ve Q yalnızca ile eşleşmeyen değerleri dikkate alarak giriş türü için P₁.
  • P bir discard_pattern ve desen giriş değerinin türü için desen Q kümesi kapsamlıdır ve desen giriş değeri null atanabilir türde değildir veya içindeki Q bir desen ile eşleşirnull.
  • içindeki Q bazı desenler bir disjunctive_patternQ₁ or Q₂ ve bu deseni ile Q₁Q değiştirmek, alt toplamları Poluşturan veya ile Q₂ değiştiren bir kümenin alt Pdizinini oluşturacağı bir küme oluşturur.
  • içindeki Q bazı desenler bir negated_patternnot Q₁ ve P eşleşebilecek Q₁ hiçbir değerle eşleşmez.

11.4 Desen tükenmişliği

Boş değer dışındaki her olası değer için kümedeki bir desen geçerliyse, kayıt dışı olarak bir tür için desen kümesi çok kapsamlıdır. Aşağıdaki kurallar, bir tür için bir dizi desenin ne zaman kapsamlı olduğunu tanımlar:

Aşağıdaki koşullardan herhangi biri geçerliyse, bir tür için bir dizi desen Q kapsamlıdır:T

  1. T tamsayı veya sabit listesi türü ya da bunlardan birinin null atanabilir bir sürümüdür ve 'nin null atanamaz temel türündeki Ther olası değer için içindeki bazı desenler Q bu değerle eşleşir; veya
  2. içindeki Q bazı desenler var desenidir; veya
  3. içindeki Q bazı desen, türü için bir D ve bir kimlik dönüştürmesi, örtük başvuru dönüştürmesi veya ile arasında bir kutulama dönüştürmesi TDvardır.
  4. içindeki Q bazı desenler türü için bir D ve bir kimlik dönüştürmesi, örtük başvuru dönüştürmesi veya ile arasında bir kutulama dönüştürmesi TDvardır.
  5. içindeki Q bazı desenler bir discard_pattern veya
  6. içindeki Q desenler, aralıkları null atanamayan temel türün herolası değerini toplu olarak kapsayan Tbirleşimini içerir. ve türleri içinfloat, herhangi bir ilişkisel desenle eşleşmediğinden buna sırasıyla double veya System.Double.NaN dahildirSystem.Single.NaN; veya NaN
  7. içindeki Q bazı desenler bir disjunctive_patternP₁ or P₂ ve bu deseni hem hem P₁P₂ de içindeki Q ile değiştirmek; veya için T bir küme verir.
  8. içindeki Q bazı desenler bir negated_patternnot P₁ ve değerleriyle birlikte içindeki Q desenler ile eşleşmeyen P₁ desenler her olası değerini Tkapsar. negated_patternnot P₁, hiçbir olası değeriyle P₁eşleşmediğinde T kendi başına çok kapsamlıdır; veya
  9. içindeki Q bazı desenler bir conjunctive_patternP₁ and P₂ ve yalnızca P₁ içeren küme için T ve yalnızca P₂ içeren küme için T.

Not: Tür deseni null atanabilir türler içerdiğinde, desen türü için kapsamlı olabilir ancak yine de bir uyarı oluşturur çünkü tür deseni bir null değerle eşleşmez. son not

Not: Kayan nokta türleri için, hiçbir ilişkisel desen < 0 eşleşmediğinden >= 0desenlerin birleşimi ve kapsamlı NaN. Doğru kapsamlı küme , ve < 0 (veya >= 0) olabilirdouble.NaN. float.NaN son not

Örnek:

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;
    }
}

son örnek