Bagikan melalui


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

Anda menggunakan is 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. Pola dapat dikombinasikan menggunakan kata kunci andlogika Boolean , , ordan not.

Ekspresi dan pernyataan C# berikut mendukung pencocokan pola:

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

  • Pola deklarasi: untuk memeriksa jenis run-time ekspresi dan, jika kecocokan berhasil, menetapkan hasil ekspresi ke variabel yang dideklarasikan.
  • Pola jenis: untuk memeriksa jenis run-time ekspresi.
  • Pola konstanta: untuk menguji bahwa hasil ekspresi sama dengan konstanta tertentu.
  • Pola relasional: untuk menguji apakah hasil ekspresi sama dengan konstanta yang ditentukan.
  • Pola logis: untuk menguji bahwa ekspresi cocok dengan kombinasi pola logis.
  • Pola properti: untuk menguji bahwa properti atau bidang ekspresi cocok dengan pola berlapis.
  • Pola posisi: untuk mendekonstruksi hasil ekspresi dan menguji apakah nilai yang dihasilkan cocok dengan pola berlapis.
  • var pola: untuk mencocokkan ekspresi apa pun dan menetapkan hasilnya ke variabel yang dideklarasikan.
  • Pola buang: untuk mencocokkan ekspresi apa pun.
  • Pola daftar: untuk menguji bahwa urutan elemen cocok dengan pola berlapis yang sesuai. Diperkenalkan dalam C# 11.

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 berdasarkan data, lihat Tutorial: Menggunakan pencocokan pola untuk membangun algoritma berdasarkan jenis dan berdasarkan data.

Deklarasi dan pola jenis

Anda menggunakan deklarasi dan pola jenis untuk memeriksa apakah jenis run-time dari ekspresi kompatibel dengan jenis yang diberikan. Dengan pola deklarasi, Anda juga dapat mendeklarasikan variabel lokal baru. Saat pola deklarasi cocok dengan ekspresi, variabel tersebut diberi 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:

  • Jenis run-time dari hasil ekspresi adalah 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. 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 jenis nilai yang dapat diubah ke null dengan jenis dasar T.

  • Konversi boxing atau unboxing sudah ada dari jenis run-time hasil ekspresi ke tipe T.

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
}

Jika Anda hanya ingin memeriksa jenis ekspresi, Anda dapat menggunakan _ buang sebagai ganti 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, Anda dapat menggunakan 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, Anda dapat menggunakan pola 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

Anda menggunakan 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 merupakan jenis yang dapat dikonversi ke jenis konstanta, dengan satu pengecualian: Ekspresi yang berjenis Span<char> atau ReadOnlySpan<char> dapat dicocokkan dengan string konstanta dalam C# 11 dan versi yang lebih baru.

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

Anda menggunakan 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

Anda menggunakan notcombinator 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 diurutkan berdasarkan urutan pengikatan ekspresi sebagai berikut:

  • not
  • and
  • or

Pola not mengikat ke operand-nya terlebih dahulu. Pola and mengikat setelah pengikatan ekspresi pola apa pun not . Pola or mengikat setelah semua not dan and pola terikat ke 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 memperbaikinya, Anda harus menentukan bahwa Anda ingin not mengikat 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

Anda menggunakan 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 bukan null dan setiap pola bersarang cocok dengan properti atau bidang yang sesuai dari hasil ekspresi.

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

Pola properti adalah pola rekursif. Artinya, Anda dapat menggunakan pola apa pun sebagai pola bersarang. 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.

Tip

Anda dapat menggunakan aturan gaya Sederhanakan pola properti (IDE0170) untuk meningkatkan keterbacaan kode dengan menyarankan tempat untuk menggunakan pola properti yang diperluas.

Pola posisional

Anda menggunakan pola posisional untuk mendekonstruksi hasil 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",
};

Pada contoh sebelumnya, jenis ekspresi berisi metode Deconstruct, yang digunakan untuk mendekonstruksi hasil ekspresi.

Penting

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

Anda juga dapat mencocokkan ekspresi jenis tuple dengan pola posisi. Dengan begitu, 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

Anda menggunakan var pola untuk mencocokkan ekspresi apa pun, termasuk null, dan menetapkan 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 .

Dalam pola var, 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

Anda menggunakan pola _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, pola buang digunakan untuk menangani null dan nilai bilangan bulat apa pun yang tidak memiliki anggota enumerasi DayOfWeek yang sesuai. Itu menjamin bahwa ekspresi switch 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

Dimulai dengan C# 11, 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 dicocokkan 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, 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 di C# 8 dan yang lebih baru, lihat catatan proposal fitur berikut:

Lihat juga