Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
11.1 Umum
Pola adalah bentuk sindikasi yang dapat digunakan dengan is operator (§12.15.12), dalam switch_statement (§13.8.3), dan dalam switch_expression (§12.12) untuk mengekspresikan bentuk data yang data masuknya akan dibandingkan. Pola mungkin rekursif, sehingga bagian data dapat dicocokkan dengan sub-pola.
Pola diuji terhadap nilai dalam sejumlah konteks:
- Dalam pernyataan switch, pola label kasus diuji terhadap ekspresi pernyataan switch.
- Dalam operator is-pattern , pola di sisi kanan diuji terhadap ekspresi di sebelah kiri.
- Dalam ekspresi pengalihan, polaswitch_expression_arm diuji terhadap ekspresi di sisi kiri ekspresi switch.
- Dalam konteks berlapis, sub-pola diuji terhadap nilai yang diambil dari properti, bidang, atau diindeks dari nilai input lainnya, tergantung pada formulir pola.
Nilai di mana pola diuji disebut nilai input pola.
11.2 Formulir pola
11.2.1 Umum
Pola mungkin memiliki salah satu formulir berikut:
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 ')'
;
Produksi '(' pattern ')' memungkinkan pola diapit dalam tanda kurung untuk menegakkan urutan evaluasi di antara pola yang dikombinasikan menggunakan salah satu logical_pattern.
Beberapa poladapat menghasilkan deklarasi variabel lokal.
Setiap formulir pola mendefinisikan kumpulan jenis untuk nilai input tempat pola dapat diterapkan. Pola Pberlaku 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
vadalahTextReader. Variabel jenisTextReadertidak pernah dapat memiliki nilai yang kompatibel dengan referensi denganstring: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
vadalahobject. Variabel jenisobjectdapat memiliki nilai yang kompatibel dengan referensi denganstring: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.
Urutan evaluasi operasi dan efek samping selama pencocokan pola (panggilan ke Deconstruct, akses properti, dan pemanggilan metode dalam System.ITuple) tidak ditentukan.
11.2.2 Pola deklarasi
declaration_pattern digunakan untuk menguji bahwa nilai memiliki jenis tertentu dan, jika pengujian berhasil, untuk secara opsional memberikan nilai dalam variabel jenis tersebut.
declaration_pattern
: type simple_designation
;
simple_designation
: discard_designation
| single_variable_designation
;
discard_designation
: '_'
;
single_variable_designation
: identifier
;
Simple_designation dengan token _ akan dianggap sebagai discard_designation daripada single_variable_designation.
Jenis runtime nilai diuji terhadap jenis dalam pola menggunakan aturan yang sama yang ditentukan dalam operator tipe is (§12.15.12.1). Jika pengujian berhasil, pola cocok dengan nilai tersebut. Ini adalah kesalahan kompilasi-waktu jika jenis adalah jenis nilai nullable (§8.3.12) atau jenis referensi nullable (§8.9.3). Bentuk pola ini tidak pernah cocok dengan null nilai.
Catatan: Ekspresi
e is Tis-type dan polae is T _deklarasi setara ketikaTbukan jenis nullable. catatan akhir
Mengingat nilai input pola (§11,1) e, jika simple_designationdiscard_designation, itu menunjukkan pembuangan (§9.2.9.2), 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 tidak, jika simple_designationsingle_variable_designation, 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 dengan jenis T jika ada konversi identitas, konversi referensi implisit atau eksplisit, konversi tinju, konversi pembuka kotak, atau konversi jenis nilai nullable implisit atau eksplisit dari E ke T, atau jika salah satu E atau T merupakan jenis terbuka (§8.4.3). Pola deklarasi penamaan jenis Tberlaku 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
Contoh: Pola deklarasi dapat digunakan untuk menguji nilai jenis null: nilai jenis
Nullable<T>(atau kotakT) cocok dengan polaT2 idjenis jika nilainya non-null danT2adalahT, atau beberapa jenis dasar atau antarmukaT. Misalnya, dalam fragmen kodeint? x = 3; if (x is int v) { /* code using v */ }Kondisi
ifpernyataan adalahtruepada runtime dan variabelvmemegang nilai3jenisintdi dalam blok. Setelah blok variabelvberada dalam cakupan, tetapi tidak pasti ditetapkan. 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 Pkonstanta 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
Pcocok dengan nilai e jika hasil ekspresie == vadalahtrue; sebaliknya - pola
Pcocok dengan nilai e jika mengembalikanobject.Equals(e, v).true
Contoh: Pernyataan
switchdalam 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_patterncocok dengan setiap nilai. Artinya, operasi pencocokan pola dengan var_pattern selalu berhasil.
Var_patternberlaku untuk setiap jenis.
var_pattern
: 'var' designation
;
designation
: simple_designation
| tuple_designation
;
tuple_designation
: '(' designations? ')'
;
designations
: designation (',' designation)*
;
Mengingat nilai input pola (§11,1) e, jika penandaandiscard_designation, itu menunjukkan pembuangan (§9.2.9.2), 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 tidak, jika penunjukansingle_variable_designation, pada runtime nilai e terikat ke variabel lokal yang baru diperkenalkan (§9,2,9) dari nama tersebut 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.
Jika penandaan adalah tuple_designation, polanya setara dengan positional_pattern (§11,2,5) dari (var formulir, ...
) di mana penetapanadalah yang ditemukan dalam tuple_designation. Misalnya, polanya var (x, (y, z)) setara dengan (var x, (var y, var z)).
11.2.5 Pola posisi
positional_pattern memeriksa bahwa nilai input bukan null, memanggil metode yang sesuai Deconstruct (§12,7), dan melakukan pencocokan pola lebih lanjut pada nilai yang dihasilkan. Ini juga mendukung sintaks pola seperti tuple (tanpa jenis yang disediakan) ketika jenis nilai input sama dengan jenis yang berisi Deconstruct, atau jika jenis nilai input adalah jenis tuple, atau jika jenis nilai input adalah atau jika jenis nilai input adalah object atau System.ITuple dan jenis runtime ekspresi mengimplementasikan System.ITuple.
positional_pattern
: type? '(' subpatterns? ')' property_subpattern? simple_designation?
;
subpatterns
: subpattern (',' subpattern)*
;
subpattern
: pattern
| subpattern_name ':' pattern
;
subpattern_name
: identifier
| subpattern_name '.' identifier
;
Mengingat kecocokan nilai input dengansubpattern(jenis) pola, metode dipilih dengan mencari dalam jenis untuk deklarasi Deconstruct yang dapat diakses dan memilih satu di antaranya menggunakan aturan yang sama seperti untuk deklarasi dekonstruksi.
Ini adalah kesalahan jika positional_pattern menghilangkan jenis, memiliki satu subpattern tanpa pengidentifikasi, tidak memiliki property_subpattern dan tidak memiliki simple_designation. Ini membedakan antara constant_pattern yang dikurung dan positional_pattern.
Untuk mengekstrak nilai yang cocok dengan pola dalam daftar,
- Jika jenis dihilangkan dan jenis ekspresi input adalah jenis tuple, maka jumlah subpattern harus sama dengan kardinalitas tuple. Setiap elemen tuple dicocokkan dengan subpattern yang sesuai, dan kecocokan berhasil jika semua ini berhasil. Jika ada subpattern yang memiliki pengidentifikasi, maka itu akan memberi nama elemen tuple pada posisi yang sesuai dalam jenis tuple.
- Jika tidak, jika cocok
Deconstructada sebagai anggota jenis, itu adalah kesalahan waktu kompilasi jika jenis nilai input tidak kompatibel dengan pola dengan jenis. Pada runtime, nilai input diuji terhadap jenis. Jika ini gagal, maka kecocokan pola posisi gagal. Jika berhasil, nilai input dikonversi ke jenis ini danDeconstructdipanggil dengan variabel segar yang dihasilkan kompilator untuk menerima parameter output. Setiap nilai yang diterima dicocokkan dengan subpattern yang sesuai, dan kecocokan berhasil jika semua ini berhasil. Jika ada subpattern yang memiliki pengidentifikasi, maka itu akan memberi nama parameter pada posisi yang sesuai dariDeconstruct. - Jika tidak, jika jenis dihilangkan, dan nilai input berjenis
objectatau beberapa jenis yang dapat dikonversi keSystem.ITupleoleh konversi referensi implisit, dan tidak adaSystem.ITupleyang muncul di antara subpattern, maka kecocokan menggunakan . - Jika tidak, polanya adalah kesalahan waktu kompilasi.
Urutan di mana subpattern dicocokkan pada runtime tidak ditentukan, dan kecocokan yang gagal mungkin tidak mencoba mencocokkan semua subpattern.
Contoh: Di sini, kami mendekonstruksi hasil ekspresi dan mencocokkan nilai yang dihasilkan dengan pola berlapis yang sesuai:
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); }contoh akhir
Contoh: Nama elemen tuple dan parameter Dekonstruksi dapat digunakan dalam pola posisional, sebagai berikut:
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); }Output yang dihasilkan adalah
Sum of [10 20 30] is 60contoh akhir
11.2.6 Pola properti
property_pattern memeriksa bahwa nilai input bukan null, dan secara rekursif cocok dengan nilai yang diekstrak oleh penggunaan properti atau bidang yang dapat diakses.
property_pattern
: type? property_subpattern simple_designation?
;
property_subpattern
: '{' '}'
| '{' subpatterns ','? '}'
;
Ini adalah kesalahan jika subpatterndari property_pattern tidak berisi subpattern_name.
Ini adalah kesalahan kompilasi-waktu jika jenis adalah jenis nilai nullable (§8.3.12) atau jenis referensi nullable (§8.9.3).
Catatan: Pola pemeriksaan null keluar dari pola properti sepele. Untuk memeriksa apakah string
snon-null, seseorang dapat menulis salah satu formulir berikut:#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 {}) ...catatan akhir
Mengingat kecocokan ekspresi e dengansubpattern{jenis} pola, itu adalah kesalahan waktu kompilasi jika ekspresi e tidak kompatibel dengan jenis T yang ditunjuk berdasarkan jenis. Jika jenis tidak ada, jenis diasumsikan sebagai jenis statis e. Setiap subpattern_name yang muncul di sisi kiri subpattern-nya akan menunjuk properti atau bidang T yang dapat dibaca yang dapat diakses. Jika simple_designationproperty_pattern ada, itu mendeklarasikan variabel pola jenis T.
Pada runtime, ekspresi diuji terhadap T. Jika ini gagal, maka kecocokan pola properti gagal, dan hasilnya adalah false. Jika berhasil, maka setiap bidang atau properti property_subpattern dibaca, dan nilainya cocok dengan pola yang sesuai. Hasil dari seluruh kecocokan false hanya jika hasil dari salah satu dari ini adalah false. Urutan di mana subpattern dicocokkan tidak ditentukan, dan kecocokan yang gagal mungkin tidak menguji semua subpattern saat runtime. Jika kecocokan berhasil dan simple_designationproperty_pattern adalah single_variable_designation, variabel yang dideklarasikan diberi nilai yang cocok.
property_pattern dapat digunakan untuk pencocokan pola dengan jenis anonim.
Subpattern_name dapat mereferensikan anggota berlapis. Dalam kasus seperti itu, penerima untuk setiap pencarian nama adalah jenis anggota sebelumnya T₀, mulai dari jenis inputproperty_pattern. Jika T adalah jenis nullable, T₀ adalah jenis yang mendasarnya, jika tidak , T₀ sama dengan T. Misalnya, pola formulir { Prop1.Prop2: pattern } sama persis dengan { Prop1: { Prop2: pattern } }.
Catatan: Ini akan menyertakan pemeriksaan null ketika T adalah jenis nilai nullable atau jenis referensi. Pemeriksaan null ini berarti bahwa properti berlapis yang tersedia akan menjadi properti T₀, bukan dari T. Karena jalur anggota berulang diizinkan, kompilasi pencocokan pola dapat memanfaatkan bagian pola umum. catatan akhir
Contoh:
var o = ...; if (o is string { Length: 5 } s) ...contoh akhir
Contoh: Pemeriksaan jenis run-time dan deklarasi variabel dapat ditambahkan ke pola properti, sebagai berikut:
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."), };Output yang dihasilkan adalah
Hello Hi! 12345 abccontoh akhir
11.2.7 Buang pola
Setiap ekspresi cocok dengan pola buang, yang menghasilkan nilai ekspresi yang dibuang.
discard_pattern
: '_'
;
Ini adalah kesalahan waktu kompilasi untuk menggunakan pola buang dalam relational_expressionpolais bentuk atau sebagai pola switch_label.
Catatan: Dalam kasus tersebut, untuk mencocokkan ekspresi apa pun, gunakan var_pattern dengan buang
var _. catatan akhir
Contoh:
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, };Output yang dihasilkan adalah
5.0 0.0 0.0Di sini, pola buang digunakan untuk menangani
nulldan nilai bilangan bulat apa pun yang tidak memiliki anggota enumerasi yangDayOfWeeksesuai. Itu menjamin bahwaswitchekspresi menangani semua kemungkinan nilai input. contoh akhir
11.2.8 Pola jenis
type_pattern digunakan untuk menguji bahwa nilai input pola (§11,1) memiliki jenis tertentu.
type_pattern
: type
;
Pola jenis penamaan jenis Tberlaku untuk setiap jenis E yang Ekompatibel dengan T pola (§11.2.2).
Jenis runtime nilai diuji terhadap jenis menggunakan aturan yang sama yang ditentukan dalam operator tipe is (§12.15.12.1). Jika pengujian berhasil, pola cocok dengan nilai tersebut. Ini adalah kesalahan waktu kompilasi jika jenisnya adalah jenis yang dapat diubah ke null. Bentuk pola ini tidak pernah cocok dengan null nilai.
11.2.9 Pola relasional
relational_pattern digunakan untuk menguji nilai input pola secara relasional (§11,1) terhadap nilai konstanta.
relational_pattern
: '<' relational_expression
| '<=' relational_expression
| '>' relational_expression
| '>=' relational_expression
;
relational_expression dalam relational_pattern diperlukan untuk mengevaluasi ke nilai konstanta.
Pola relasional mendukung operator <relasional , , <=>, dan >= pada semua jenis bawaan yang mendukung operator relasional biner tersebut dengan kedua operan memiliki jenis yang sama: sbyte, , , byteshort, ushortintuintlongulongcharfloatdoubledecimal, nint, nuint, , dan enum.
relational_patternberlaku untuk jenis T jika operator relasional biner bawaan yang sesuai didefinisikan dengan kedua operan jenis T, atau jika konversi nullable atau unboxing eksplisit ada dari T ke jenis ekspresi konstanta.
Ini adalah kesalahan waktu kompilasi jika ekspresi mengevaluasi ke double.NaN, float.NaN, atau konstanta null.
Ketika nilai input memiliki jenis yang didefinisikan oleh operator relasional biner bawaan yang sesuai, evaluasi operator tersebut diambil sebagai arti pola relasional. Jika tidak, nilai input dikonversi ke jenis ekspresi konstanta menggunakan konversi nullable atau unboxing eksplisit. Ini adalah kesalahan waktu kompilasi jika tidak ada konversi tersebut. Pola dianggap tidak cocok jika konversi gagal. Jika konversi berhasil, hasil operasi pencocokan pola adalah hasil mengevaluasi ekspresi e «op» v di mana e adalah input yang dikonversi, «op» adalah operator relasional, dan v merupakan ekspresi konstanta.
Contoh:
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", };Output yang dihasilkan adalah
Too high Unknown Acceptablecontoh akhir
11.2.10 Pola logis
logical_pattern digunakan untuk meniadakan hasil kecocokan pola, atau untuk menggabungkan hasil dari beberapa kecocokan pola menggunakan sambungan (and) atau disjunksi (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, and, dan or secara kolektif disebut operator pola.
Negated_pattern cocok jika pola yang ditiadakan tidak cocok, dan sebaliknya.
conjunctive_pattern mengharuskan kedua pola untuk dicocokkan.
Disjunctive_pattern memerlukan salah satu pola untuk dicocokkan. Tidak seperti rekan operator bahasa mereka, && dan ||, and dan orbukan operator sirkuit pendek.
Ini adalah kesalahan waktu kompilasi agar variabel pola dideklarasikan di bawah not operator pola atau or .
Catatan: Karena tidak juga tidak
notordapat menghasilkan penugasan pasti untuk variabel pola, kesalahan untuk mendeklarasikannya dalam posisi tersebut. catatan akhir
Dalam conjunctive_pattern, jenis input pola kedua dipersempit oleh persyaratan penyempitan jenis pola pertama .and Jenis pola yang P didefinisikan sebagai berikut:
- Jika
Padalah pola jenis, jenis yang dipersempit adalah jenis jenis pola jenis. - Jika tidak, jika
Padalah pola deklarasi, jenis yang dipersempit adalah jenis pola deklarasi. - Jika tidak, jika
Padalah pola rekursif yang memberikan jenis eksplisit, jenis yang dipersempit adalah jenis tersebut. - Jika tidak, jika
Pdicocokkan melalui aturan untukITupledalam positional_pattern (§11.2.5), jenis yang dipersempit adalah jenisSystem.ITuple. - Jika tidak, jika
Padalah pola konstanta di mana konstanta bukan konstanta null dan di mana ekspresi tidak memiliki konversi ekspresi konstanta ke jenis input, jenis yang dipersempit adalah jenis konstanta. - Jika tidak, jika
Padalah pola relasional di mana ekspresi konstanta tidak memiliki konversi ekspresi konstan ke jenis input, jenis yang dipersempit adalah jenis konstanta. - Jika tidak, jika
Padalahorpola, jenis yang dipersempit adalah jenis umum dari jenis subpattern yang dipersempit jika jenis umum seperti itu ada. Untuk tujuan ini, algoritma jenis umum hanya mempertimbangkan konversi identitas, tinju, dan referensi implisit, dan mempertimbangkan semua subpatternordari urutan pola (mengabaikan pola yang dikurung). - Jika tidak, jika
Padalahandpola, jenis yang dipersempit adalah jenis pola yang tepat yang dipersempit . Selain itu, jenis pola kiri yang dipersempit adalah jenis input pola kanan. - Jika tidak , jenis
Pyang dipersempit adalahPjenis input.
Catatan: Seperti yang ditunjukkan oleh tata bahasa,
notlebih diutamakan daripadaand, yang lebih diutamakan daripadaor. Ini dapat secara eksplisit ditunjukkan atau ditimpa dengan menggunakan tanda kurung. catatan akhir
Ketika pola muncul di sisi iskanan , tingkat pola ditentukan oleh tata bahasa; sebagai hasilnya, operator andpola , , ordan not dalam pola mengikat lebih ketat daripada operator &&logis , , ||dan ! di luar pola.
Contoh:
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", };Output yang dihasilkan adalah
High Too low Acceptablecontoh akhir
Contoh:
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}."), };Output yang dihasilkan adalah
winter autumn springcontoh akhir
Contoh:
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}");Output yang dihasilkan adalah
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: Truecontoh akhir
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 Pakan cocok dengan konstanta K jika salah satu kondisi berikut menahan:
- spesifikasi untuk perilaku runtime pola tersebut adalah yang
PcocokKdengan . -
Padalah type_pattern untuk jenisTdanKbukannulldan jenisKruntime adalahTatau jenis yang berasal dariTatau jenis yang mengimplementasikanT. -
Padalah relational_pattern dengan operator «op» dan konstantav, dan ekspresiK«op»vakan mengevaluasi ketrue. -
Padalah negated_patternnot P₁danP₁tidak akan cocokK. -
Padalah conjunctive_patternP₁ and P₂dan keduanyaP₁akan cocokKdanP₂akan cocokK. -
Padalah disjunctive_patternP₁ or P₂dan akanP₁cocokKatauP₂akan cocokK. -
Padalah discard_pattern.
Sekumpulan pola mensubsumsi Qpola P jika salah satu kondisi berikut menahan:
-
Padalah pola konstanta dan salah satu pola dalam setQakan cocokPdengan nilai yang dikonversi -
Padalah pola var dan kumpulan pola lengkapQ -
Padalah pola deklarasi dengan jenisTdan kumpulan polaQlengkap untuk jenisT(§11.4). -
Padalah type_pattern untuk jenisTdan kumpulan polaQlengkap untuk jenisT. -
Padalah relational_pattern dengan operator «op» dan nilaivkonstanta , dan untuk setiap nilai jenis input yang memenuhi relasi «op»v, beberapa pola dalam setQakan cocok dengan nilai tersebut. -
Padalah disjunctive_patternP₁ or P₂dan set subjudulQP₁danQsubjudulP₂pola . -
Padalah conjunctive_patternP₁ and P₂dan setidaknya salah satu penangguhan berikut:QsubjudulP₁, atauQsubjudulP₂. -
Padalah negated_patternnot P₁danQlengkap untuk jenis input yang hanya mempertimbangkan nilai yang tidak cocok denganP₁. -
Padalah discard_pattern dan kumpulan polaQlengkap untuk jenis nilai input pola, dan nilai input pola bukan dari jenis nullable atau beberapa pola diQakan cocoknulldengan . - Beberapa pola dalam
Qadalah disjunctive_patternQ₁ or Q₂dan mengganti pola tersebut denganQ₁inQakan menghasilkan set yang subsumesP, atau menggantinya denganQ₂akan menghasilkan set yang subsumesP. - Beberapa pola dalam
Qadalah negated_patternnot Q₁danPtidak akan cocok dengan nilai apa pun yangQ₁cocok.
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:
-
Tadalah jenis integral atau enum, atau versi nullable dari salah satunya, dan untuk setiap nilai yang mungkin dariTjenis yang mendasar yang tidak dapat diubah ke null, beberapa pola akanQcocok dengan nilai tersebut; atau - Beberapa pola dalam
Qadalah pola var; atau - Beberapa pola dalam
Qadalah pola deklarasi untuk jenisD, dan ada konversi identitas, konversi referensi implisit, atau konversi tinju dariTkeD; atau - Beberapa pola dalam
Qadalah type_pattern untuk jenisD, dan ada konversi identitas, konversi referensi implisit, atau konversi tinju dariTkeD; atau - Beberapa pola dalam
Qadalah discard_pattern; atau - Pola termasuk
Qkombinasi relational_patterndan constant_patternyang rentangnya secara kolektif mencakup setiap nilai yang mungkin dariTjenis yang mendasar yang tidak dapat diubah ke null. Untukfloatjenis dandouble, ini mencakupSystem.Double.NaNatauSystem.Single.NaNmasing-masing,NaNkarena tidak cocok dengan pola relasional apa pun; atau - Beberapa pola dalam
Qadalah disjunctive_patternP₁ or P₂, dan mengganti pola tersebut dengan keduanyaP₁danP₂dalamQmenghasilkan satu set yang lengkap untukT; atau - Beberapa pola dalam
Qadalah negated_patternnot P₁, dan pola bersamaQdengan nilai yang tidak cocok denganP₁mencakup setiap nilai yang mungkin dariT. negated_patternnot P₁lengkap dengan sendirinya ketikaP₁tidak cocok dengan nilaiTyang mungkin ; atau - Beberapa pola dalam
Qadalah conjunctive_patternP₁ and P₂, dan set yang hanyaP₁berisi lengkap untukTdan set yang hanyaP₂berisi lengkap untukT.
Catatan: Ketika pola jenis menyertakan jenis nullable, pola mungkin lengkap untuk jenis tetapi masih menghasilkan peringatan karena pola jenis tidak akan cocok dengan
nullnilai. catatan akhir
Catatan: Untuk jenis floating-point, kombinasi pola
< 0dan>= 0tidak lengkap karena pola relasional tidak cocokNaN. Set lengkap yang benar adalah< 0, ,>= 0dandouble.NaN(ataufloat.NaN). catatan akhir
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
ECMA C# draft specification