Bagikan melalui


Pencocokan pola - is ekspresi dan switch , dan operator and, or, dan not dalam pola

is Gunakan ekspresi, pernyataan pengalihan, dan ekspresi pengalihan untuk mencocokkan ekspresi input dengan sejumlah karakteristik. C# mendukung beberapa pola, termasuk deklarasi, jenis, konstanta, relasional, properti, daftar, var, dan buang. Anda dapat menggabungkan pola dengan menggunakan kata kunci andlogika Boolean , , ordan not.

Referensi bahasa C# mendokumentasikan versi bahasa C# yang paling baru dirilis. Ini juga berisi dokumentasi awal untuk fitur dalam pratinjau publik untuk rilis bahasa yang akan datang.

Dokumentasi mengidentifikasi fitur apa pun yang pertama kali diperkenalkan dalam tiga versi terakhir bahasa atau dalam pratinjau publik saat ini.

Petunjuk / Saran

Untuk menemukan kapan fitur pertama kali diperkenalkan di C#, lihat artikel tentang riwayat versi bahasa C#.

Ekspresi dan pernyataan C# berikut mendukung pencocokan pola:

Dalam konstruksi tersebut, Anda dapat mencocokkan ekspresi input dengan salah satu pola berikut:

  • Pola deklarasi: periksa jenis run-time ekspresi dan, jika kecocokan berhasil, tetapkan hasil ekspresi ke variabel yang dideklarasikan.
  • Pola tipe: periksa tipe run-time dari ekspresi.
  • Pola konstanta: uji bahwa hasil ekspresi sama dengan konstanta tertentu.
  • Pola relasional: membandingkan hasil ekspresi dengan konstanta tertentu.
  • Pola logis: uji bahwa ekspresi cocok dengan kombinasi pola logis.
  • Pola properti: uji bahwa properti atau bidang ekspresi cocok dengan pola berlapis.
  • Pola posisi: mendekonstruksi hasil ekspresi dan menguji apakah nilai yang dihasilkan cocok dengan pola berlapis.
  • var pola: cocokkan ekspresi apa pun dan tetapkan hasilnya ke variabel yang dideklarasikan.
  • Buang pola: cocok dengan ekspresi apa pun.
  • Pola daftar: uji bahwa urutan elemen cocok dengan pola berlapis yang sesuai.

Pola logis, properti, posisi, dan daftar adalah pola rekursif . Artinya, pola tersebut dapat berisi pola bersarang.

Untuk contoh cara menggunakan pola tersebut untuk membangun algoritma berbasis data, lihat Tutorial: Menggunakan pencocokan pola untuk membangun algoritma berbasis jenis dan berbasis data.

Deklarasi dan pola jenis

Gunakan pola deklarasi dan jenis untuk memeriksa apakah jenis run-time ekspresi kompatibel dengan jenis tertentu. Dengan pola deklarasi, Anda juga dapat mendeklarasikan variabel lokal baru. Saat pola deklarasi cocok dengan ekspresi, variabel ditetapkan ke hasil ekspresi yang dikonversi, seperti yang ditunjukkan contoh berikut:

object greeting = "Hello, World!";
if (greeting is string message)
{
    Console.WriteLine(message.ToLower());  // output: hello, world!
}

Pola deklarasi dengan jenis T cocok dengan ekspresi saat hasil ekspresi non-null dan salah satu kondisi berikut ini benar:

  • Tipe run-time dari hasil ekspresi memiliki konversi identitas ke T.
  • Jenisnya T adalah ref struct jenis dan ada konversi identitas dari ekspresi ke T.
  • Jenis run-time dari hasil ekspresi berasal dari jenis T, mengimplementasikan antarmuka T, atau konversi referensi implisit lainya yang sudah ada darinya ke T. Kondisi ini mencakup hubungan warisan dan implementasi antarmuka. Contoh berikut menunjukkan dua kasus ketika kondisi ini benar:
    var numbers = new int[] { 10, 20, 30 };
    Console.WriteLine(GetSourceLabel(numbers));  // output: 1
    
    var letters = new List<char> { 'a', 'b', 'c', 'd' };
    Console.WriteLine(GetSourceLabel(letters));  // output: 2
    
    static int GetSourceLabel<T>(IEnumerable<T> source) => source switch
    {
        Array array => 1,
        ICollection<T> collection => 2,
        _ => 3,
    };
    
    Dalam contoh sebelumnya, pada panggilan pertama ke metode GetSourceLabel, pola pertama cocok dengan nilai argumen karena tipe run-time argumen int[] berasal dari jenis Array. Pada panggilan kedua ke metode GetSourceLabel, jenis run-time argumen List<T> tidak diturunkan dari jenis Array, tetapi mengimplementasikan antarmuka ICollection<T>.
  • Jenis run-time dari hasil ekspresi adalah tipe nilai nullable dengan tipe yang mendasarinya dan T adalah Nullable<T>.HasValue.
  • Konversi penyematan atau pembongkaran merupakan dari tipe run-time hasil ekspresi ke tipe T ketika ekspresi bukan instance dari ref struct.

Pola deklarasi tidak mempertimbangkan konversi yang ditentukan pengguna atau konversi rentang implisit.

Contoh berikut menunjukkan dua kondisi terakhir:

int? xNullable = 7;
int y = 23;
object yBoxed = y;
if (xNullable is int a && yBoxed is int b)
{
    Console.WriteLine(a + b);  // output: 30
}

Untuk memeriksa hanya jenis ekspresi, gunakan buang _ sebagai pengganti nama variabel, seperti yang ditunjukkan contoh berikut:

public abstract class Vehicle {}
public class Car : Vehicle {}
public class Truck : Vehicle {}

public static class TollCalculator
{
    public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
    {
        Car _ => 2.00m,
        Truck _ => 7.50m,
        null => throw new ArgumentNullException(nameof(vehicle)),
        _ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
    };
}

Untuk tujuan tersebut, gunakan pola jenis, seperti yang ditunjukkan contoh berikut:

public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
{
    Car => 2.00m,
    Truck => 7.50m,
    null => throw new ArgumentNullException(nameof(vehicle)),
    _ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};

Seperti pola deklarasi, pola jenis cocok dengan ekspresi ketika hasil ekspresi non-null dan jenis run-time-nya memenuhi salah satu kondisi sebelumnya.

Untuk memeriksa non-null, gunakanpola konstanta yang dinegasikan, seperti yang ditunjukkan null contoh berikut:

if (input is not null)
{
    // ...
}

Untuk informasi lebih lanjut, lihat bagian Pola deklarasi dan Pola jenis dari catatan proposal fitur.

Pola konstanta

Pola konstanta adalah sintaks alternatif untuk == ketika operand di sebelah kanan adalah konstanta. Gunakan pola konstanta untuk menguji apakah hasil ekspresi sama dengan konstanta tertentu, seperti yang ditunjukkan contoh berikut:

public static decimal GetGroupTicketPrice(int visitorCount) => visitorCount switch
{
    1 => 12.0m,
    2 => 20.0m,
    3 => 27.0m,
    4 => 32.0m,
    0 => 0.0m,
    _ => throw new ArgumentException($"Not supported number of visitors: {visitorCount}", nameof(visitorCount)),
};

Dalam pola konstanta, Anda dapat menggunakan ekspresi konstanta apa pun, seperti:

Ekspresi harus berupa jenis yang dapat dikonversi ke jenis konstanta, dengan satu pengecualian: Ekspresi yang jenisnya Span<char> atau ReadOnlySpan<char> dapat dicocokkan dengan string konstanta.

Gunakan pola konstan untuk memeriksa null, seperti yang ditunjukkan contoh berikut:

if (input is null)
{
    return;
}

Kompilator menjamin bahwa tidak ada operator persamaan overload pengguna == yang dipanggil saat ekspresi x is null dievaluasi.

Anda dapat menggunakan pola konstanta yang dinegasikannull untuk memeriksa non-null, seperti yang ditunjukkan contoh berikut:

if (input is not null)
{
    // ...
}

Untuk informasi lebih lanjut, lihat bagian Pola konstanta dari catatan proposal fitur.

Pola relasional

Gunakan pola relasional untuk membandingkan hasil ekspresi dengan konstanta, seperti yang ditunjukkan contoh berikut:

Console.WriteLine(Classify(13));  // output: Too high
Console.WriteLine(Classify(double.NaN));  // output: Unknown
Console.WriteLine(Classify(2.4));  // output: Acceptable

static string Classify(double measurement) => measurement switch
{
    < -4.0 => "Too low",
    > 10.0 => "Too high",
    double.NaN => "Unknown",
    _ => "Acceptable",
};

Dalam pola relasional, Anda dapat menggunakan salah satu operator<relasional , , ><=, atau >=. Bagian kanan dari pola relasional harus berupa ekspresi konstanta. Ekspresi konstanta dapat berupa integer, floating-point, char, atau enum.

Untuk memeriksa apakah hasil ekspresi berada dalam rentang tertentu, cocokkan dengan pola andkonjungtif, seperti yang ditunjukkan contoh berikut:

Console.WriteLine(GetCalendarSeason(new DateTime(2021, 3, 14)));  // output: spring
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 7, 19)));  // output: summer
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 2, 17)));  // output: winter

static string GetCalendarSeason(DateTime date) => date.Month switch
{
    >= 3 and < 6 => "spring",
    >= 6 and < 9 => "summer",
    >= 9 and < 12 => "autumn",
    12 or (>= 1 and < 3) => "winter",
    _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};

Jika hasil ekspresi adalah null atau gagal dikonversi ke jenis konstanta dengan konversi yang dapat diubah ke null atau unboxing, pola relasional tidak cocok dengan ekspresi.

Untuk informasi lebih lanjut, lihat bagian Pola relasional dari catatan proposal fitur.

Pola logika

notGunakan combinator pola , and, dan or untuk membuat pola logis berikut:

  • Pola negasinot yang cocok dengan ekspresi saat pola yang dinegasikan tidak cocok dengan ekspresi. Contoh berikut menunjukkan bagaimana Anda dapat meniadakan pola konstantanull untuk memeriksa apakah ekspresi bukan null:

    if (input is not null)
    {
        // ...
    }
    
  • Pola konjunctifand yang cocok dengan ekspresi saat kedua pola cocok dengan ekspresi. Contoh berikut menunjukkan bagaimana Anda dapat menggabungkan pola relasional untuk memeriksa apakah suatu nilai berada dalam rentang tertentu:

    Console.WriteLine(Classify(13));  // output: High
    Console.WriteLine(Classify(-100));  // output: Too low
    Console.WriteLine(Classify(5.7));  // output: Acceptable
    
    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",
    };
    
  • Pola disjunctiveor yang cocok dengan ekspresi saat salah satu pola cocok dengan ekspresi, seperti yang ditunjukkan contoh berikut:

    Console.WriteLine(GetCalendarSeason(new DateTime(2021, 1, 19)));  // output: winter
    Console.WriteLine(GetCalendarSeason(new DateTime(2021, 10, 9)));  // output: autumn
    Console.WriteLine(GetCalendarSeason(new DateTime(2021, 5, 11)));  // output: spring
    
    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}."),
    };
    

Seperti yang ditunjukkan oleh contoh sebelumnya, Anda dapat berulang kali menggunakan penyatu pola dalam pola.

Prioritas dan urutan pemeriksaan

Combinator pola mengikuti urutan ini, berdasarkan urutan ekspresi pengikatan:

  • not
  • and
  • or

Pola not mengikat ke operand-nya terlebih dahulu. Pola and mengikat setelah pengikatan ekspresi pola apa pun not . Pola mengikat or setelah semua not dan and pola mengikat operand. Contoh berikut mencoba mencocokkan semua karakter yang bukan huruf kecil, a - z. Ini memiliki kesalahan, karena pola mengikat not sebelum and pola:

// Incorrect pattern. `not` binds before `and`
static bool IsNotLowerCaseLetter(char c) => c is not >= 'a' and <= 'z';

Pengikatan default berarti contoh sebelumnya diurai sebagai contoh berikut:

// The default binding without parentheses is shows in this method. `not` binds before `and`
static bool IsNotLowerCaseLetterDefaultBinding(char c) => c is ((not >= 'a') and <= 'z');

Untuk memperbaiki kesalahan, tentukan bahwa Anda ingin pola mengikat not ekspresi >= 'a' and <= 'z' :

// Correct pattern. Force `and` before `not`
static bool IsNotLowerCaseLetterParentheses(char c) => c is not (>= 'a' and <= 'z');

Menambahkan tanda kurung menjadi lebih penting karena pola Anda menjadi lebih rumit. Secara umum, gunakan tanda kurung untuk mengklarifikasi pola Anda untuk pengembang lain, seperti yang ditunjukkan contoh berikut:

static bool IsLetter(char c) => c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z');

Catatan

Urutan di mana pola yang memiliki urutan pengikatan yang sama diperiksa tidak ditentukan. Pada run time, pola berlapis kanan dari beberapa or pola dan beberapa and pola dapat diperiksa terlebih dahulu.

Untuk informasi lebih lanjut, lihat bagian Penyatu pola dari catatan proposal fitur.

Pola properti

Gunakan pola properti untuk mencocokkan properti atau bidang ekspresi dengan pola berlapis, seperti yang ditunjukkan contoh berikut:

static bool IsConferenceDay(DateTime date) => date is { Year: 2020, Month: 5, Day: 19 or 20 or 21 };

Pola properti cocok dengan ekspresi saat hasil ekspresi non-null dan setiap pola berlapis cocok dengan properti atau bidang yang sesuai dari hasil ekspresi.

Anda dapat menambahkan pemeriksaan jenis run-time dan deklarasi variabel ke pola properti, seperti yang ditunjukkan contoh 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."),
};

Konstruksi ini secara khusus berarti bahwa pola is { } properti kosong cocok dengan semuanya non-null, dan Anda dapat menggunakannya alih-alih is not null membuat variabel: somethingPossiblyNull is { } somethingDefinitelyNotNull.

if (GetSomeNullableStringValue() is { } nonNullValue) // Empty property pattern with variable creation
{
    Console.WriteLine("NotNull:" + nonNullValue);
}
else
{
    nonNullValue = "NullFallback"; // we can access the variable here.
    Console.WriteLine("it was null, here's the fallback: " + nonNullValue);
}

Pola properti adalah pola rekursif. Anda dapat menggunakan pola apa pun sebagai pola berlapis. Gunakan pola properti untuk mencocokkan bagian data dengan pola bersarang, seperti yang ditunjukkan contoh berikut:

public record Point(int X, int Y);
public record Segment(Point Start, Point End);

static bool IsAnyEndOnXAxis(Segment segment) =>
    segment is { Start: { Y: 0 } } or { End: { Y: 0 } };

Contoh sebelumnya menggunakan orcombinator pola dan jenis rekaman.

Anda dapat mereferensikan properti atau bidang berlapis dalam pola properti. Kemampuan ini dikenal sebagai pola properti yang diperluas. Misalnya, Anda dapat merefaktor metode dari contoh sebelumnya ke dalam kode yang setara berikut:

static bool IsAnyEndOnXAxis(Segment segment) =>
    segment is { Start.Y: 0 } or { End.Y: 0 };

Untuk informasi lebih lanjut, lihat bagian Pola properti dari catatan proposal fitur dan catatan proposal fitur Pola properti yang diperluas.

Petunjuk / Saran

Untuk meningkatkan keterbacaan kode, gunakan aturan gaya Sederhanakan pola properti (IDE0170). Ini menyarankan tempat untuk menggunakan pola properti yang diperluas.

Pola posisional

Gunakan pola posisional untuk mendekonstruksi ekspresi dan mencocokkan nilai yang dihasilkan dengan pola berlapis yang sesuai, seperti yang ditunjukkan contoh berikut:

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

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

Dalam contoh sebelumnya, jenis ekspresi berisi metode Dekonstruksi , yang digunakan pola untuk mendekonstruksi hasil ekspresi.

Penting

Urutan anggota dalam pola posisi harus cocok dengan urutan parameter dalam Deconstruct metode . Kode yang dihasilkan untuk pola posisi memanggil Deconstruct metode .

Anda juga dapat mencocokkan ekspresi jenis tuple dengan pola posisi. Dengan menggunakan pendekatan ini, Anda dapat mencocokkan beberapa input dengan berbagai pola, seperti yang ditunjukkan contoh berikut:

static decimal GetGroupTicketPriceDiscount(int groupSize, DateTime visitDate)
    => (groupSize, visitDate.DayOfWeek) switch
    {
        (<= 0, _) => throw new ArgumentException("Group size must be positive."),
        (_, DayOfWeek.Saturday or DayOfWeek.Sunday) => 0.0m,
        (>= 5 and < 10, DayOfWeek.Monday) => 20.0m,
        (>= 10, DayOfWeek.Monday) => 30.0m,
        (>= 5 and < 10, _) => 12.0m,
        (>= 10, _) => 15.0m,
        _ => 0.0m,
    };

Contoh sebelumnya menggunakan pola relasional dan logis .

Anda dapat menggunakan nama elemen tuple dan parameter Deconstruct dalam pola posisional, seperti yang ditunjukkan contoh berikut:

var numbers = new List<int> { 1, 2, 3 };
if (SumAndCount(numbers) is (Sum: var sum, Count: > 0))
{
    Console.WriteLine($"Sum of [{string.Join(" ", numbers)}] is {sum}");  // output: Sum of [1 2 3] is 6
}

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

Anda juga dapat memperluas pola posisi dengan salah satu cara berikut:

  • Tambahkan pemeriksaan jenis run-time dan deklarasi variabel, seperti yang ditunjukkan contoh berikut:

    public record Point2D(int X, int Y);
    public record Point3D(int X, int Y, int Z);
    
    static string PrintIfAllCoordinatesArePositive(object point) => point switch
    {
        Point2D (> 0, > 0) p => p.ToString(),
        Point3D (> 0, > 0, > 0) p => p.ToString(),
        _ => string.Empty,
    };
    

    Contoh sebelumnya menggunakan rekaman posisional yang secara implisit menyediakan metode Deconstruct.

  • Gunakan pola properti dalam pola posisional, seperti yang ditunjukkan contoh berikut:

    public record WeightedPoint(int X, int Y)
    {
        public double Weight { get; set; }
    }
    
    static bool IsInDomain(WeightedPoint point) => point is (>= 0, >= 0) { Weight: >= 0.0 };
    
  • Gabungkan dua penggunaan sebelumnya, seperti yang ditunjukkan contoh berikut:

    if (input is WeightedPoint (> 0, > 0) { Weight: > 0.0 } p)
    {
        // ..
    }
    

Pola posisional adalah pola rekursif. Artinya, Anda dapat menggunakan pola apa pun sebagai pola bersarang.

Untuk informasi lebih lanjut, lihat bagian Pola posisional dari catatan proposal fitur.

Pola var

var Gunakan pola untuk mencocokkan ekspresi apa pun, termasuk null, dan tetapkan hasilnya ke variabel lokal baru, seperti yang ditunjukkan contoh berikut:

static bool IsAcceptable(int id, int absLimit) =>
    SimulateDataFetch(id) is var results 
    && results.Min() >= -absLimit 
    && results.Max() <= absLimit;

static int[] SimulateDataFetch(int id)
{
    var rand = new Random();
    return Enumerable
               .Range(start: 0, count: 5)
               .Select(s => rand.Next(minValue: -10, maxValue: 11))
               .ToArray();
}

Pola var berguna saat Anda membutuhkan variabel sementara dalam ekspresi Boolean untuk menampung hasil penghitungan perantara. Anda juga dapat menggunakan var pola saat Anda perlu melakukan lebih banyak pemeriksaan jika terjadi penjaga when ekspresi atau pernyataan, seperti yang ditunjukkan switch contoh berikut:

public record Point(int X, int Y);

static Point Transform(Point point) => point switch
{
    var (x, y) when x < y => new Point(-x, y),
    var (x, y) when x > y => new Point(x, -y),
    var (x, y) => new Point(x, y),
};

static void TestTransform()
{
    Console.WriteLine(Transform(new Point(1, 2)));  // output: Point { X = -1, Y = 2 }
    Console.WriteLine(Transform(new Point(5, 2)));  // output: Point { X = 5, Y = -2 }
}

Dalam contoh sebelumnya, pola var (x, y) setara dengan pola(var x, var y)posisi .

var Dalam pola, jenis variabel yang dideklarasikan adalah jenis waktu kompilasi ekspresi yang cocok dengan pola.

Untuk informasi lebih lanjut, lihat bagian pola Var dari catatan proposal fitur.

Pola buang

Gunakan pola _buang untuk mencocokkan ekspresi apa pun, termasuk null, seperti yang ditunjukkan contoh berikut:

Console.WriteLine(GetDiscountInPercent(DayOfWeek.Friday));  // output: 5.0
Console.WriteLine(GetDiscountInPercent(null));  // output: 0.0
Console.WriteLine(GetDiscountInPercent((DayOfWeek)10));  // output: 0.0

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

Dalam contoh sebelumnya, gagang null pola buang dan nilai bilangan bulat apa pun yang tidak memiliki anggota DayOfWeek enumerasi yang sesuai. Jaminan itu memastikan bahwa switch ekspresi dalam contoh menangani semua kemungkinan nilai input. Jika Anda tidak menggunakan pola buang dalam ekspresi switch dan tidak ada pola ekspresi yang cocok dengan input, waktu proses melempar pengecualian. Pengompilasi menghasilkan peringatan jika ekspresi switch tidak menangani semua kemungkinan nilai input.

Pola buang tidak boleh berupa pola dalam ekspresi is atau pernyataan switch. Dalam kasus tersebut, untuk mencocokkan ekspresi apa pun, gunakan pola var dengan membuang: var _. Pola buang bisa menjadi pola dalam switch ekspresi.

Untuk informasi lebih lanjut, lihat bagian Pola Buang dari catatan proposal fitur.

Pola tanda kurung

Anda dapat menempatkan tanda kurung di sekitar pola apa pun. Biasanya, Anda melakukannya untuk menekankan atau mengubah prioritas dalam pola logis, seperti yang ditunjukkan contoh berikut:

if (input is not (float or double))
{
    return;
}

Pola daftar

Anda dapat mencocokkan array atau daftar dengan urutan pola, seperti yang ditunjukkan contoh berikut:

int[] numbers = { 1, 2, 3 };

Console.WriteLine(numbers is [1, 2, 3]);  // True
Console.WriteLine(numbers is [1, 2, 4]);  // False
Console.WriteLine(numbers is [1, 2, 3, 4]);  // False
Console.WriteLine(numbers is [0 or 1, <= 2, >= 3]);  // True

Seperti yang ditunjukkan contoh sebelumnya, pola daftar cocok ketika setiap pola berlapis cocok dengan elemen yang sesuai dari urutan input. Anda dapat menggunakan pola apa pun dalam pola daftar. Untuk mencocokkan elemen apa pun, gunakan pola buang atau, jika Anda juga ingin mengambil elemen, gunakan pola var, seperti yang ditunjukkan contoh berikut:

List<int> numbers = new() { 1, 2, 3 };

if (numbers is [var first, _, _])
{
    Console.WriteLine($"The first element of a three-item list is {first}.");
}
// Output:
// The first element of a three-item list is 1.

Contoh sebelumnya cocok dengan seluruh urutan input terhadap pola daftar. Untuk mencocokkan elemen hanya di awal atau/dan akhir urutan input, gunakan pola..ikhtisar , seperti yang ditunjukkan contoh berikut:

Console.WriteLine(new[] { 1, 2, 3, 4, 5 } is [> 0, > 0, ..]);  // True
Console.WriteLine(new[] { 1, 1 } is [_, _, ..]);  // True
Console.WriteLine(new[] { 0, 1, 2, 3, 4 } is [> 0, > 0, ..]);  // False
Console.WriteLine(new[] { 1 } is [1, 2, ..]);  // False

Console.WriteLine(new[] { 1, 2, 3, 4 } is [.., > 0, > 0]);  // True
Console.WriteLine(new[] { 2, 4 } is [.., > 0, 2, 4]);  // False
Console.WriteLine(new[] { 2, 4 } is [.., 2, 4]);  // True

Console.WriteLine(new[] { 1, 2, 3, 4 } is [>= 0, .., 2 or 4]);  // True
Console.WriteLine(new[] { 1, 0, 0, 1 } is [1, 0, .., 0, 1]);  // True
Console.WriteLine(new[] { 1, 0, 1 } is [1, 0, .., 0, 1]);  // False

Pola ilis cocok dengan nol atau lebih elemen. Anda dapat menggunakan paling banyak satu pola ilis dalam pola daftar. Pola ilis hanya dapat muncul dalam pola daftar.

Anda juga dapat menumpuk subpattern dalam pola ipotong, seperti yang ditunjukkan contoh berikut:

void MatchMessage(string message)
{
    var result = message is ['a' or 'A', .. var s, 'a' or 'A']
        ? $"Message {message} matches; inner part is {s}."
        : $"Message {message} doesn't match.";
    Console.WriteLine(result);
}

MatchMessage("aBBA");  // output: Message aBBA matches; inner part is BB.
MatchMessage("apron");  // output: Message apron doesn't match.

void Validate(int[] numbers)
{
    var result = numbers is [< 0, .. { Length: 2 or 4 }, > 0] ? "valid" : "not valid";
    Console.WriteLine(result);
}

Validate(new[] { -1, 0, 1 });  // output: not valid
Validate(new[] { -1, 0, 0, 1 });  // output: valid

Untuk informasi selengkapnya, lihat catatan proposal fitur Pola daftar.

Spesifikasi bahasa C#

Untuk informasi selengkapnya, lihat bagian Pola dan pencocokan pola dari spesifikasi bahasa C#.

Untuk informasi tentang fitur yang ditambahkan dalam C# 9 dan versi yang lebih baru, lihat catatan proposal fitur berikut:

Lihat juga