Bagikan melalui


11 Pola dan pencocokan pola

11.1 Umum

Pola adalah bentuk sintaktik yang dapat digunakan dengan is operator (§12.12.12) dan dalam switch_statement (§13.8.3) untuk mengekspresikan bentuk data yang data masuknya akan dibandingkan. Pola diuji terhadap ekspresi pernyataan pengalihan, atau terhadap relational_expression yang berada di sisi is kiri operator, yang masing-masing disebut sebagai nilai input pola.

11.2 Formulir pola

11.2.1 Umum

Pola mungkin memiliki salah satu formulir berikut:

pattern
    : declaration_pattern
    | constant_pattern
    | var_pattern
    ;

declaration_pattern dan var_pattern dapat menghasilkan deklarasi variabel lokal.

Setiap formulir pola mendefinisikan kumpulan jenis untuk nilai input tempat pola dapat diterapkan. Pola P berlaku untuk jenis T jika T berada di antara jenis yang nilainya mungkin cocok dengan pola. Ini adalah kesalahan waktu kompilasi jika pola P muncul dalam program untuk mencocokkan nilai input pola (§11.1) jenis T jika P tidak berlaku untuk T.

Contoh: Contoh berikut menghasilkan kesalahan waktu kompilasi karena jenis waktu kompilasi v adalah TextReader. Variabel jenis TextReader tidak pernah dapat memiliki nilai yang kompatibel dengan referensi dengan string:

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

Namun, berikut ini tidak menghasilkan kesalahan waktu kompilasi karena jenis waktu kompilasi v adalah object. Variabel jenis object dapat memiliki nilai yang kompatibel dengan referensi dengan string:

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

contoh akhir

Setiap formulir pola mendefinisikan kumpulan nilai yang polanya cocok dengan nilai saat runtime.

11.2.2 Pola deklarasi

declaration_pattern digunakan untuk menguji bahwa nilai memiliki jenis tertentu dan, jika pengujian berhasil, berikan nilai dalam variabel jenis tersebut.

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

Jenis runtime nilai diuji terhadap jenis dalam pola menggunakan aturan yang sama yang ditentukan dalam operator is-type (§12.12.12.1). Jika pengujian berhasil, pola cocok dengan nilai tersebut. Ini adalah kesalahan waktu kompilasi jika jenisnya adalah jenis nilai nullable (§8.3.12). Bentuk pola ini tidak pernah cocok dengan null nilai.

Catatan: Ekspresi e is T is-type dan pola e is T _ deklarasi setara jika T bukan jenis nullable. catatan akhir

Mengingat nilai input pola (§11,1) e, jika simple_designation adalah pengidentifikasi _ , itu menunjukkan pembuangan (§9.2.9.1) dan nilai e tidak terikat pada apa pun. (Meskipun variabel yang dideklarasikan dengan nama _ mungkin berada dalam cakupan pada saat itu, variabel bernama tersebut tidak terlihat dalam konteks ini.) Jika simple_designation adalah pengidentifikasi lain, variabel lokal (§9.2.9) dari jenis yang diberikan yang dinamai oleh pengidentifikasi yang diberikan diperkenalkan. Variabel lokal tersebut diberi nilai nilai input pola saat pola cocok dengan nilai.

Kombinasi tertentu dari jenis statis nilai input pola dan jenis yang diberikan dianggap tidak kompatibel dan mengakibatkan kesalahan waktu kompilasi. Nilai jenis E statis dikatakan kompatibel dengan pola T jika ada konversi identitas, konversi referensi implisit atau eksplisit, konversi tinju, atau konversi pembuka kotak dari E ke T, atau jika salah satu E atau T merupakan jenis terbuka (§8.4.3). Pola deklarasi penamaan jenis T berlaku untuk setiap jenis E yang E kompatibel dengan pola .T

Catatan: Dukungan untuk jenis terbuka dapat paling berguna saat memeriksa jenis yang mungkin berupa jenis struct atau kelas, dan tinju harus dihindari. catatan akhir

Contoh: Pola deklarasi berguna untuk melakukan pengujian jenis run-time dari jenis referensi, dan menggantikan idiom

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

dengan sedikit lebih ringkas

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

contoh akhir

Ini adalah kesalahan jika jenis adalah jenis nilai nullable.

Contoh: Pola deklarasi dapat digunakan untuk menguji nilai jenis null: nilai jenis Nullable<T> (atau kotak T) cocok dengan pola T2 id jenis jika nilainya non-null dan T2 adalah T, atau beberapa jenis dasar atau antarmuka T. Misalnya, dalam fragmen kode

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

Kondisi if pernyataan adalah true pada runtime dan variabel v memegang nilai 3 jenis int di dalam blok. contoh akhir

11.2.3 Pola konstanta

constant_pattern digunakan untuk menguji nilai nilai input pola (§11,1) terhadap nilai konstanta yang diberikan.

constant_pattern
    : constant_expression
    ;

Pola P konstanta berlaku untuk jenis T jika ada konversi implisit dari ekspresi P konstanta ke jenis T.

Untuk pola Pkonstanta , nilai yang dikonversi adalah

  • jika jenis nilai input pola adalah jenis integral atau jenis enum, nilai konstanta pola dikonversi ke jenis tersebut; Sebaliknya
  • jika jenis nilai input pola adalah versi nullable dari jenis integral atau jenis enum, nilai konstan pola dikonversi ke jenis yang mendasarnya; Sebaliknya
  • nilai nilai konstanta pola.

Mengingat nilai input pola e dan pola P konstanta dengan nilai yang dikonversi v,

  • jika e memiliki jenis integral atau jenis enum, atau bentuk nullable dari salah satunya, dan v memiliki jenis integral, pola P cocok dengan nilai e jika hasil ekspresi e == v adalah true; sebaliknya
  • pola P cocok dengan nilai e jika object.Equals(e, v) mengembalikan true.

Contoh: Pernyataan switch dalam metode berikut menggunakan lima pola konstanta dalam label kasusnya.

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

contoh akhir

Pola 11.2.4 Var

Var_pattern cocok dengan setiap nilai. Artinya, operasi pencocokan pola dengan var_pattern selalu berhasil.

Var_pattern berlaku untuk setiap jenis.

var_pattern
    : 'var' designation
    ;
designation
    : simple_designation
    ;

Mengingat nilai input pola (§11,1) e, jika penandaan adalah pengidentifikasi _ , itu menunjukkan pembuangan (§9.2.9.1), dan nilai e tidak terikat ke apa pun. (Meskipun variabel yang dideklarasikan dengan nama tersebut mungkin berada dalam cakupan pada saat itu, variabel bernama tersebut tidak terlihat dalam konteks ini.) Jika penandaan adalah pengidentifikasi lain, pada runtime nilai e terikat ke variabel lokal yang baru diperkenalkan (§9,2,9) dari nama yang jenisnya adalah jenis statis e, dan nilai input pola ditetapkan ke variabel lokal tersebut.

Ini adalah kesalahan jika nama var akan mengikat ke jenis tempat var_pattern digunakan.

11.3 Subsumpsi pola

Dalam pernyataan pengalihan, itu adalah kesalahan jika pola kasus disubsumsikan oleh kumpulan kasus yang tidak dijaga sebelumnya (§13.8.3). Secara informal, ini berarti bahwa nilai input apa pun akan dicocokkan oleh salah satu kasus sebelumnya. Aturan berikut menentukan kapan sekumpulan pola mensubsumsi pola tertentu:

Pola P akan cocok dengan konstanta K jika spesifikasi untuk perilaku runtime pola tersebut cocok dengan P K.

Sekumpulan pola mensubsumsi Q pola P jika salah satu kondisi berikut menahan:

  • Padalah pola konstanta dan salah satu pola dalam set Q akan cocok Pdengan nilai yang dikonversi
  • Padalah pola var dan kumpulan pola lengkap (§11,4) untuk jenis nilai input pola (§11.1), dan nilai input pola bukan dari jenis nullable atau beberapa pola di Q akan cocok null. Q
  • Padalah pola deklarasi dengan jenis T dan kumpulan pola Q lengkap untuk jenis T (§11.4).

11.4 Kelelahan pola

Secara informal, satu set pola lengkap untuk jenis jika, untuk setiap nilai yang mungkin dari jenis itu selain null, beberapa pola dalam set berlaku. Aturan berikut menentukan kapan sekumpulan pola lengkap untuk jenis:

Sekumpulan pola Q lengkap untuk jenis T jika salah satu kondisi berikut menahan:

  1. T adalah jenis integral atau enum, atau versi nullable dari salah satunya, dan untuk setiap nilai yang mungkin dari Tjenis yang mendasar yang tidak dapat diubah ke null, beberapa pola akan Q cocok dengan nilai tersebut; atau
  2. Beberapa pola dalam Q adalah pola var; atau
  3. Beberapa pola dalam Q adalah pola deklarasi untuk jenis D, dan ada konversi identitas, konversi referensi implisit, atau konversi tinju dari T ke D.

Contoh:

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

contoh akhir