Aracılığıyla paylaş


11 Desen ve desen eşleştirme

11.1 Genel

Desen, gelen verilerin karşılaştırılacağı veri şeklini ifade etmek için işleç (§12.12.12) ve switch_statement (§13.8.3) ile is kullanılabilen söz dizimsel bir formdur. Desen, switch deyiminin ifadesinde veya işlecin sol tarafında bulunan ve her biri desen giriş değeri olarak adlandırılan biris relational_expression karşı test edilir.

11.2 Desen formları

11.2.1 Genel

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

pattern
    : declaration_pattern
    | constant_pattern
    | var_pattern
    ;

bir declaration_pattern ve bir var_pattern bir yerel değişkenin bildirimine neden olabilir.

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ındaysaT, T bir tür için geçerlidir. 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, derleme zamanı türü v olduğundan objectaşağıdakiler derleme 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.

11.2.2 Bildirim düzeni

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

declaration_pattern
    : type simple_designation
    ;
simple_designation
    : single_variable_designation
    ;
single_variable_designation
    : identifier
    ;

Değerin çalışma zamanı türü, is-type işlecinde (§12.12.12.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üyse (§8.3.12) 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

Desen giriş değeri (§11.1) e verildiğinde, simple_designation tanımlayıcı _ ise at (§9.2.9.1) 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.) simple_designation başka bir tanımlayıcıysa, verilen tanımlayıcı tarafından adlandırılan türe ait 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, bir kutulama dönüştürmesi veya 'den E Tgelen kutulama açma dönüştürmesi varsa ya da açık bir türse T E (§8.4.3) türüyle T uyumlu desenle uyumlu olduğu söylenir. Bir türü T adlandıran bildirim deseni, deseni ile Tuyumlu olan E her tür E için 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

Tür null atanabilir bir değer türüyse hatadır.

Örnek: Bildirim deseni, null atanabilir türlerin değerlerini test etmek için kullanılabilir: değer null olmayan ve T2 Tise tür deseni Nullable<T> (veya kutuluT) bir tür deseni T2 id 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 int değerini 3 tutar. 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 T örtük bir dönüştürme varsa, bir tür Tiçin sabit desen P 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.

E desen giriş değeri ve dönüştürülen v değerine sahip 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 e == v sonucu ise desen P e değeriyle eşleşirtrue; aksi takdirde
  • deseni P döndürürse object.Equals(e, v) e değeriyle eşleşirtrue.

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

Desen giriş değeri (§11.1) e verildiğinde, atama tanımlayıcı _ ise atılan değeri (§9.2.9.1) 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.) Atama başka bir tanımlayıcıysa, çalışma zamanında e değeri, türü statik e türü olan ve desen giriş değeri bu yerel değişkene atanan 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.

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:

Bu desenin P çalışma zamanı davranışının P belirtimi ile eşleşiyorsa bir desen sabitle K eşleşirK.

Bir dizi desen Q , aşağıdaki koşullardan herhangi biri geçerliyse bir desenin P alt dizinini oluşturur:

  • Psabit bir desendir ve kümedeki Q desenlerden herhangi biri 'nin dönüştürülmüş değeriyle eşleşir P
  • Pbir var desenidir ve desen Q kümesi desen giriş değerinin türü (§11.1) için kapsamlıdır (§11.4) ve desen giriş değeri null atanabilir türde değildir veya içindeki Q bir desen eşleşirnull.
  • Ptürüne T sahip bir bildirim desenidir ve desen Q kümesi tür T için kapsamlıdır (§11.4).

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ı desenler türü Diçin bir bildirim desenidir 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 T Dvardır.

Ö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