Desenler (C# başvurusu)

C#, C# 7.0'da desen eşleştirmeyi kullanıma sunar. O zamandan beri, her ana C# sürümü desen eşleştirme özelliklerini genişletir. Aşağıdaki C# ifadeleri ve deyimleri desen eşleştirmeyi destekler:

Bu yapılarda, bir giriş ifadesini aşağıdaki desenlerden herhangi biriyle eşleştirebilirsiniz:

  • Bildirim deseni: bir ifadenin çalışma zamanı türünü denetlemek ve eşleşme başarılı olursa bildirilen değişkene bir ifade sonucu atamak için. C# 7.0 ile kullanıma sunulmuştur.
  • Tür deseni: bir ifadenin çalışma zamanı türünü denetlemek için. C# 9.0 ile kullanıma sunulmuştur.
  • Sabit desen: bir ifade sonucunun belirtilen sabite eşit olup olmadığını test etmek için. C# 7.0 ile kullanıma sunulmuştur.
  • İlişkisel desenler: bir ifade sonucunu belirtilen sabitle karşılaştırmak için. C# 9.0 ile kullanıma sunulmuştur.
  • Mantıksal desenler: bir ifadenin desenlerin mantıksal birleşimiyle eşleşip eşleşmediğini test etmek için. C# 9.0 ile kullanıma sunulmuştur.
  • Özellik deseni: bir ifadenin özelliklerinin veya alanlarının iç içe desenlere uygun olup olmadığını test etmek için. C# 8.0 ile kullanıma sunulmuştur.
  • Konumsal desen: bir ifade sonucunun yapısından çıkıp sonuçta elde edilen değerlerin iç içe desenlerle eşleşip eşleşmediğini test etmek için. C# 8.0 ile kullanıma sunulmuştur.
  • var pattern: herhangi bir ifadeyi eşleştirmek ve sonucunu bildirilen bir değişkene atamak için. C# 7.0 ile kullanıma sunulmuştur.
  • Deseni at: herhangi bir ifadeyle eşleşmesi için. C# 8.0 ile kullanıma sunulmuştur.

Mantıksal, özellik ve konumsal desenler özyinelemeli desenlerdir . Yani, iç içe desenler içerebilirler.

Veri temelli algoritma oluşturmak için bu desenlerin nasıl kullanılacağı örneği için bkz . Öğretici: Tür temelli ve veri temelli algoritmalar oluşturmak için desen eşleştirmeyi kullanma.

Bildirim ve tür desenleri

Bir ifadenin çalışma zamanı türünün belirli bir türle uyumlu olup olmadığını denetlemek için bildirim ve tür desenlerini kullanırsınız. Bildirim deseniyle, yeni bir yerel değişken de bildirebilirsiniz. Bildirim deseni bir ifadeyle eşleştiğinde, aşağıdaki örnekte gösterildiği gibi bu değişkene dönüştürülmüş bir ifade sonucu atanır:

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

C# 7.0 sürümünden başlayarak, bir T ifade sonucu null olmadığında ve aşağıdaki koşullardan herhangi biri doğru olduğunda türe sahip bir bildirim deseni ifadeyle eşleşir:

  • İfade sonucunun çalışma zamanı türü olur T.

  • bir ifade sonucunun çalışma zamanı türü türünden Ttüretilir, arabirimini Tuygular veya türünden Töğesine başka bir örtük başvuru dönüştürmesi vardır. Aşağıdaki örnekte, bu koşulun doğru olduğu iki durum gösterilmektedir:

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

    Yukarıdaki örnekte, yöntemine yapılan ilk çağrıda, bağımsız değişkenin çalışma zamanı türü int[] türünden türetildiği için GetSourceLabel ilk desen bir bağımsız değişken değeriyle Array eşleşir. yöntemine GetSourceLabel yapılan ikinci çağrıda, bağımsız değişkenin çalışma zamanı türü List<T> türünden Array türetilmez, ancak arabirimini ICollection<T> uygular.

  • bir ifade sonucunun çalışma zamanı türü, temel türüne sahip null atanabilir bir değer türüdürT.

  • İfade sonucunun çalışma zamanı türünden türüne Tbir kutulama veya kutu açma dönüştürmesi vardır.

Aşağıdaki örnekte son iki koşul gösterilmektedir:

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

Bir ifadenin yalnızca türünü denetlemek istiyorsanız, aşağıdaki örnekte gösterildiği gibi değişkenin adı yerine atma _ kullanabilirsiniz:

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

C# 9.0 sürümünden başlayarak, bu amaçla, aşağıdaki örnekte gösterildiği gibi bir tür deseni kullanabilirsiniz:

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

Bildirim deseni gibi, bir ifade sonucu null olmadığında ve çalışma zamanı türü yukarıda listelenen koşullardan herhangi birini karşıladığında tür deseni bir ifadeyle eşleşir.

Bu düzeni net ve kısa null bir denetim için de kullanabilirsiniz:

if (input is not null)
{
    Console.WriteLine(input);
} else
{
    throw new ArgumentNullException(paramName: nameof(input), message: "Input should not be null");
}

Daha fazla bilgi için özellik teklifi notlarının Bildirim deseni ve Tür deseni bölümlerine bakın.

Sabit desen

C# 7.0 sürümünden başlayarak, aşağıdaki örnekte gösterildiği gibi bir ifade sonucunun belirtilen sabite eşit olup olmadığını test etmek için sabit bir desen kullanırsınız:

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

Sabit bir desende, aşağıdaki gibi herhangi bir sabit ifadeyi kullanabilirsiniz:

İfade, sabit türe dönüştürülebilir bir tür olmalıdır; tek bir özel durum vardır: Türü C# 11 ve sonraki sürümlerde sabit dizelerle eşleştirilebilen veya ReadOnlySpan<char> bunlarla eşleştirilebilen bir ifadeSpan<char>.

Aşağıdaki örnekte gösterildiği gibi, değerini denetlemek için nullsabit bir desen kullanın:

if (input is null)
{
    return;
}

Derleyici, ifade x is null değerlendirildiğinde kullanıcı tarafından aşırı yüklenmiş eşitlik işlecinin == çağrılmadığını garanti eder.

C# 9.0 sürümünden başlayarak, aşağıdaki örnekte gösterildiği gibi null olmayanları denetlemek için negatif sabitnull deseni kullanabilirsiniz:

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

Daha fazla bilgi için özellik teklifi notunun Sabit desen bölümüne bakın.

İlişkisel desenler

C# 9.0 sürümünden başlayarak, aşağıdaki örnekte gösterildiği gibi bir ifade sonucunu sabitle karşılaştırmak için ilişkisel desen kullanırsınız:

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

İlişkisel desende, ilişkisel işleçlerden< herhangi birini , ><=veya >=kullanabilirsiniz. İlişkisel desenin sağ kısmı sabit bir ifade olmalıdır. Sabit ifade bir tamsayı, kayan nokta, karakter veya sabit listesi türünde olabilir.

Bir ifade sonucunun belirli bir aralıkta olup olmadığını denetlemek için, aşağıdaki örnekte gösterildiği gibi bunu bir konjonktif and desenle eşleştirin:

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

İfade sonucu null null atanabilir veya kutulanamayan bir dönüştürme ile sabit türüne dönüştürülemezse veya dönüştüremezse, ilişkisel desen bir ifadeyle eşleşmez.

Daha fazla bilgi için özellik teklifi notunun İlişkisel desenler bölümüne bakın.

Mantıksal desenler

C# 9.0 sürümünden notbaşlayarak, aşağıdaki mantıksal desenleri oluşturmak için , andve or desen birleştiricilerini kullanırsınız:

  • Olumsuzluknot olumsuz desen ifadeyle eşleşmediğinde bir ifadeyle eşleşen desen. Aşağıdaki örnekte, bir ifadenin null olmayan olup olmadığını denetlemek için bir sabitnull deseni nasıl iptal edebilirsiniz gösterilmektedir:

    if (input is not null)
    {
        // ...
    }
    
  • Konjonktifand her iki desen de ifadeyle eşleştiğinde bir ifadeyle eşleşen desen. Aşağıdaki örnek, bir değerin belirli bir aralıkta olup olmadığını denetlemek için ilişkisel desenleri nasıl birleştirebileceğinizi gösterir:

    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",
    };
    
  • Kararsızor desenlerden herhangi biri ifadeyle eşleştiğinde ifadeyle eşleşen desen, aşağıdaki örnekte gösterildiği gibi:

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

Yukarıdaki örnekte gösterildiği gibi, desen birleştiricilerini bir desende tekrar tekrar kullanabilirsiniz.

Öncelik ve denetim sırası

Aşağıdaki liste, en yüksek öncelikten en düşüke kadar olan düzen birleştiricilerini sıralar:

  • not
  • and
  • or

Önceliği açıkça belirtmek için aşağıdaki örnekte gösterildiği gibi parantezleri kullanın:

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

Not

Desenlerin denetlenme sırası tanımlanmamıştır. Çalışma zamanında, önce sağ taraftaki ve desenlerinin orand iç içe desenleri denetlenebilir.

Daha fazla bilgi için özellik teklifi notunun Desen birleştiricileri bölümüne bakın.

Özellik deseni

C# 8.0 sürümünden başlayarak, aşağıdaki örnekte gösterildiği gibi bir ifadenin özelliklerini veya alanlarını iç içe desenlerle eşleştirmek için özellik deseni kullanırsınız:

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

Bir ifade sonucu null olmadığında ve iç içe yerleştirilmiş her desen ifade sonucunun ilgili özelliği veya alanıyla eşleştiğinde özellik deseni bir ifadeyle eşleşir.

Aşağıdaki örnekte gösterildiği gibi, bir özellik desenine bir çalışma zamanı türü denetimi ve değişken bildirimi de ekleyebilirsiniz:

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

Özellik deseni özyinelemeli bir desendir. Başka bir ifadeyle, herhangi bir deseni iç içe desen olarak kullanabilirsiniz. Aşağıdaki örnekte gösterildiği gibi, verilerin bölümlerini iç içe desenlerle eşleştirmek için bir özellik deseni kullanın:

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

Yukarıdaki örnekte C# 9.0 ve sonraki sürümlerde kullanılabilen iki özellik kullanılabilecek: ordesen birleştiricisi ve kayıt türleri.

C# 10'undan başlayarak, bir özellik deseni içindeki iç içe özelliklere veya alanlara başvurabilirsiniz. Bu, genişletilmiş özellik deseni olarak bilinir. Örneğin, önceki örnekten yöntemini aşağıdaki eşdeğer koda yeniden düzenleyebilirsiniz:

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

Daha fazla bilgi için özellik teklifi notunun Özellik düzeni bölümüne ve Genişletilmiş özellik desenleri özellik teklifi notu'na bakın.

İpucu

Genişletilmiş özellik desenlerinin kullanılacağı yerler önererek kod okunabilirliğini geliştirmek için Özellik desenini basitleştirme (IDE0170) stil kuralını kullanabilirsiniz.

Konumsal desen

C# 8.0 sürümünden başlayarak, aşağıdaki örnekte gösterildiği gibi bir ifade sonucunun kodunu çözmek ve sonuçta elde edilen değerleri ilgili iç içe desenlerle eşleştirmek için konumsal desen kullanırsınız:

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

Yukarıdaki örnekte, bir ifadenin türü, bir ifade sonucunun yapısını çözmek için kullanılan Deconstruct yöntemini içerir. Tanımlama grubu türlerinin ifadelerini konumsal desenlerle de eşleştirebilirsiniz. Bu şekilde, aşağıdaki örnekte gösterildiği gibi çeşitli desenlerle birden çok girişi eşleştirebilirsiniz:

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

Yukarıdaki örnek, C# 9.0 ve sonraki sürümlerde kullanılabilen ilişkisel ve mantıksal desenleri kullanır.

Aşağıdaki örnekte gösterildiği gibi, tanımlama grubu öğelerinin ve Deconstruct parametrelerin adlarını konumsal bir desende kullanabilirsiniz:

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

Konumsal deseni aşağıdaki yollardan herhangi biriyle de genişletebilirsiniz:

  • Aşağıdaki örnekte gösterildiği gibi bir çalışma zamanı türü denetimi ve değişken bildirimi ekleyin:

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

    Yukarıdaki örnek örtük olarak yöntemini sağlayan Deconstructkonumsal kayıtları kullanır.

  • Aşağıdaki örnekte gösterildiği gibi konumsal desen içinde bir özellik deseni kullanın:

    public record WeightedPoint(int X, int Y)
    {
        public double Weight { get; set; }
    }
    
    static bool IsInDomain(WeightedPoint point) => point is (>= 0, >= 0) { Weight: >= 0.0 };
    
  • Aşağıdaki örnekte gösterildiği gibi önceki iki kullanımı birleştirin:

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

Konumsal desen özyinelemeli bir desendir. Başka bir ifadeyle, herhangi bir deseni iç içe desen olarak kullanabilirsiniz.

Daha fazla bilgi için özellik teklifi notunun Konumsal desen bölümüne bakın.

var desen

C# 7.0 sürümünden başlayarak, aşağıdaki örnekte gösterildiği gibi, dahil olmak üzere nullherhangi bir ifadeyle eşleştirmek için bir var desen kullanır ve sonucunu yeni bir yerel değişkene atarsınız:

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

Ara var hesaplamaların sonucunu tutmak için Boole ifadesinde geçici bir değişkene ihtiyacınız olduğunda desen kullanışlıdır. Aşağıdaki örnekte gösterildiği gibi bir var ifadenin veya deyimin korumaları durumunda ek denetimler when yapmanız gerektiğinde de bir switch desen kullanabilirsiniz:

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

Yukarıdaki örnekte desen, var (x, y)konumsal desene(var x, var y) eşdeğerdir.

Bir var desende, bildirilen değişkenin türü, desenle eşleşen ifadenin derleme zamanı türüdür.

Daha fazla bilgi için özellik teklifi notunun Var deseni bölümüne bakın.

Atma düzeni

C# 8.0 sürümünden başlayarak, aşağıdaki örnekte gösterildiği gibi dahil olmak üzere nullherhangi bir ifadeyle eşleştirmek için bir atma deseni_ kullanırsınız:

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

Yukarıdaki örnekte, numaralandırmanın ilgili üyesi olmayan herhangi bir tamsayı değerini işlemek null için bir atma deseni DayOfWeek kullanılmıştır. Bu, örnekteki bir switch ifadenin tüm olası giriş değerlerini işlemesini garanti eder. İfadede switch atma deseni kullanmıyorsanız ve ifadenin desenlerinden hiçbiri bir girişle eşleşmiyorsa, çalışma zamanı bir özel durum oluşturur. Bir ifade tüm olası giriş değerlerini işlemezse switch derleyici bir uyarı oluşturur.

Atma deseni bir ifadede veya switch deyimde is bir desen olamaz. Böyle durumlarda, herhangi bir ifadeyi eşleştirmek için atılmış bir var desen kullanın: var _.

Daha fazla bilgi için özellik teklifi notunun Deseni at bölümüne bakın.

Ayraçlı desen

C# 9.0 sürümünden başlayarak, herhangi bir desenin etrafına parantez ekleyebilirsiniz. Genellikle, aşağıdaki örnekte gösterildiği gibi, mantıksal desenlerdeki önceliği vurgular veya değiştirmek için bunu yaparsınız:

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

Liste desenleri

C# 11'le başlayarak, bir diziyi veya listeyi öğelerle eşleşen desen dizisiyle eşleştirebilirsiniz. Aşağıdaki desenlerden herhangi birini uygulayabilirsiniz:

  • Tek bir öğenin belirli özelliklerle eşleştiğinden emin olmak için herhangi bir öğeye herhangi bir desen uygulanabilir.
  • Atma düzeni (_) tek bir öğeyle eşleşir.
  • Aralık deseni (..), dizideki sıfır veya daha fazla öğeyle eşleşebilir. Liste deseninde en fazla bir aralık düzenine izin verilir.
  • Desen var tek bir öğeyi veya bir öğe aralığını yakalayabilir.

Bu kurallar aşağıdaki dizi bildirimleri kullanılarak gösterilmiştir:

int[] one = { 1 };
int[] odd = { 1, 3, 5 };
int[] even = { 2, 4, 6 };
int[] fib = { 1, 1, 2, 3, 5 };

Tüm öğeleri belirterek ve değerleri kullanarak tüm diziyi eşleştirebilirsiniz:

Console.WriteLine(odd is [1, 3, 5]); // true
Console.WriteLine(even is [1, 3, 5]); // false (values)
Console.WriteLine(one is [1, 3, 5]); // false (length)

At desenini (_) yer tutucu olarak kullanarak bilinen uzunlukta bir dizideki bazı öğeleri eşleştirebilirsiniz:

Console.WriteLine(odd is [1, _, _]); // true
Console.WriteLine(odd is [_, 3, _]); // true
Console.WriteLine(even is [_, _, 5]); // false (last value)

Sıranın herhangi bir yerinde istediğiniz sayıda değer veya yer tutucu sağlayabilirsiniz. Uzunlukla ilgilenmiyorsanız, sıfır veya daha fazla öğeyle eşleştirmek için aralık desenini kullanabilirsiniz:

Console.WriteLine(odd is [1, .., 3, _]); // true
Console.WriteLine(fib is [1, .., 3, _]); // true

Console.WriteLine(odd is [1, _, 5, ..]); // true
Console.WriteLine(fib is [1, _, 5, ..]); // false

Önceki örneklerde, bir öğenin belirli bir sayı olup olmadığını belirlemek için sabit desen kullanılmıştır. Bu desenlerden herhangi biri ilişkisel desen gibi farklı bir desenle değiştirilebilir:

Console.WriteLine(odd is [_, >1, ..]); // true
Console.WriteLine(even is [_, >1, ..]); // true
Console.WriteLine(fib is [_, > 1, ..]); // false

Liste desenleri, veriler normal bir yapıyı izlemediğinde değerli bir araçtır. Desen eşleştirmeyi kullanarak verilerin şeklini ve değerlerini bir nesne kümesine dönüştürmek yerine test edebilirsiniz.

Banka işlemlerini içeren bir metin dosyasından aşağıdaki alıntıyı göz önünde bulundurun:

04-01-2020, DEPOSIT,    Initial deposit,            2250.00
04-15-2020, DEPOSIT,    Refund,                      125.65
04-18-2020, DEPOSIT,    Paycheck,                    825.65
04-22-2020, WITHDRAWAL, Debit,           Groceries,  255.73
05-01-2020, WITHDRAWAL, #1102,           Rent, apt, 2100.00
05-02-2020, INTEREST,                                  0.65
05-07-2020, WITHDRAWAL, Debit,           Movies,      12.57
04-15-2020, FEE,                                       5.55

Bu bir CSV biçimidir, ancak bazı satırlarda diğerlerinden daha fazla sütun vardır. İşleme açısından daha da kötüsü, türdeki WITHDRAWAL bir sütunda kullanıcı tarafından oluşturulan metin bulunur ve metinde virgül bulunabilir. Değerin verileri şu biçimde işlediğini yakalamak için atma desenini, sabit deseni ve var desenini içeren bir liste deseni:

decimal balance = 0m;
foreach (var transaction in ReadRecords())
{
    balance += transaction switch
    {
        [_, "DEPOSIT", _, var amount]     => decimal.Parse(amount),
        [_, "WITHDRAWAL", .., var amount] => -decimal.Parse(amount),
        [_, "INTEREST", var amount]       => decimal.Parse(amount),
        [_, "FEE", var fee]               => -decimal.Parse(fee),
        _                                 => throw new InvalidOperationException($"Record {transaction} is not in the expected format!"),
    };
    Console.WriteLine($"Record: {transaction}, New balance: {balance:C}");
}

Yukarıdaki örnek, her öğenin satırda bir alan olduğu bir dize dizisi alır. İşlemin türünü ve kalan sütunların sayısını belirleyen ikinci alandaki anahtar ifadesi anahtarları. Her satır, verilerin doğru biçimde olmasını sağlar. Atma düzeni (_) ilk alanı atlar ve işlem tarihiyle birlikte. İkinci alan, hareketin türüyle eşleşir. Kalan öğe eşleşmeleri, tutarla alana atlar. Son eşleşme, miktarın dize gösterimini yakalamak için var desenini kullanır. İfade, bakiyenin ekleneceği veya çıkarılabilmesi için miktarı hesaplar.

Liste desenleri , bir veri öğeleri dizisinin şekliyle eşleşmenizi sağlar. Öğelerin konumuyla eşleşmesi için atma ve aralık desenlerini kullanırsınız. Tek tek öğelerle ilgili özellikleri eşleştirmek için diğer desenleri kullanırsınız.

C# dili belirtimi

Daha fazla bilgi için aşağıdaki özellik teklifi notlarını inceleyin:

Ayrıca bkz.