Aracılığıyla paylaş


Öğretici: Tür temelli ve veri temelli algoritmalar oluşturmak için desen eşleştirmeyi kullanma

Başka kütüphanelerde bulunabilecek türleri genişletmiş gibi davranan işlevsellik yazabilirsiniz. Desenler için bir diğer kullanım, uygulamanızın gerektirdiği, genişletilmekte olan türün temel bir özelliği olmayan işlevler oluşturmaktır.

Bu öğreticide aşağıdakilerin nasıl yapılacağını öğreneceksiniz:

  • Desen eşleştirmenin kullanılması gereken durumları tanıma.
  • Tür ve özellik değerlerine göre davranış uygulamak için desen eşleştirme ifadelerini kullanın.
  • Tam algoritmalar oluşturmak için desen eşleştirmeyi diğer tekniklerle birleştirin.

Önkoşullar

Yükleme yönergeleri

Windows'da tüm önkoşulları yüklemek için bu WinGet yapılandırma dosyası kullanılır. Zaten yüklü bir şey varsa WinGet bu adımı atlar.

  1. Dosyayı indirin ve çift tıklayarak çalıştırın.
  2. Lisans sözleşmesini okuyun, yyazın ve kabul etmek isteyip istemediğiniz sorulduğunda Enter seçin.
  3. Görev Çubuğunuzda yanıp sönen bir Kullanıcı Hesabı Denetimi (UAC) istemi alırsanız yüklemenin devam etmesi için izin verin.

Diğer platformlarda, bu bileşenlerin her birini ayrı ayrı yüklemeniz gerekir.

  1. Önerilen yükleyiciyi .NET SDK indirme sayfasından indirin ve çift tıklayarak çalıştırın. İndirme sayfası platformunuzu algılar ve platformunuz için en son yükleyiciyi önerir.
  2. Visual Studio Code giriş sayfasından en son yükleyiciyi indirin ve çift tıklayarak çalıştırın. Bu sayfa ayrıca platformunuzu algılar ve bağlantı sisteminiz için doğru olmalıdır.
  3. C# DevKit uzantısı sayfasındaki "Yükle" düğmesine tıklayın. Bu, Visual Studio code'u açar ve uzantıyı yüklemek mi yoksa etkinleştirmek mi istediğinizi sorar. "Yükle" seçeneğini belirleyin.

Bu öğreticide, Visual Studio veya .NET CLI dahil olmak üzere C# ve .NET hakkında bilgi sahibi olduğunuz varsayılır.

Desen eşleştirme senaryoları

Modern geliştirme genellikle birden çok kaynaktaki verileri tümleştirmeyi ve bu verilerden bilgileri ve içgörüleri tek bir uyumlu uygulamada sunmayı içerir. Siz ve ekibiniz gelen verileri temsil eden tüm türler için denetime veya erişime sahip olmayacaksınız.

Klasik nesne odaklı tasarım, uygulamanızda bu birden çok veri kaynağından her veri türünü temsil eden türler oluşturmak için çağrıda bulunur. Ardından uygulamanız bu yeni türlerle çalışır, devralma hiyerarşileri oluşturur, sanal yöntemler oluşturur ve soyutlamalar uygular. Bu teknikler işe yarar ve bazen en iyi araçlardır. Diğer durumlarda daha az kod yazabilirsiniz. Verileri bu verileri işleyen işlemlerden ayıran teknikleri kullanarak daha net kod yazabilirsiniz.

Bu öğreticide, tek bir senaryo için birkaç dış kaynaktan gelen verileri alan bir uygulama oluşturacak ve keşfedeceksiniz. Desen eşleştirmenin bu verileri özgün sistemin parçası olmayan şekillerde kullanmak ve işlemek için nasıl verimli bir yol sağladığını göreceksiniz.

Trafiği yönetmek için ücretli ve yoğun zaman fiyatlandırması kullanan büyük bir metropol alanı düşünün. Bir aracın geçiş ücretlerini türüne göre hesaplayan bir uygulama yazarsınız. Daha sonraki geliştirmelerde araçtaki kişi sayısına göre fiyatlandırma dahil edilmiştir. Diğer geliştirmeler, saat ve haftanın gününe göre fiyatlandırma ekler.

Bu kısa açıklamadan, bu sistemi modellemek için bir nesne hiyerarşisini hızla çizmiş olabilirsiniz. Ancak, verileriniz diğer araç kayıt yönetim sistemleri gibi birden fazla kaynaktan geliyor. Bu sistemler bu verileri modellemek için farklı sınıflar sağlar ve kullanabileceğiniz tek bir nesne modeliniz yoktur. Bu öğreticide, aşağıdaki kodda gösterildiği gibi bu harici sistemlerden alınan araç verilerini modellemek için bu basitleştirilmiş sınıfları kullanacaksınız:

namespace ConsumerVehicleRegistration
{
    public class Car
    {
        public int Passengers { get; set; }
    }
}

namespace CommercialRegistration
{
    public class DeliveryTruck
    {
        public int GrossWeightClass { get; set; }
    }
}

namespace LiveryRegistration
{
    public class Taxi
    {
        public int Fares { get; set; }
    }

    public class Bus
    {
        public int Capacity { get; set; }
        public int Riders { get; set; }
    }
}

Başlangıç kodunu dotnet/samples GitHub deposundan indirebilirsiniz. Araç sınıflarının farklı sistemlerden olduğunu ve farklı ad alanlarına ait olduğunu görebilirsiniz. Ortak bir temel sınıf yoktur, bunun dışında System.Object kullanılabilir.

Desen eşleştirme tasarımları

Bu öğreticide kullanılan senaryo, desen eşleştirmenin çözmek için uygun olduğu sorun türlerini vurgular:

  • Birlikte çalışmanız gereken nesneler, hedeflerinize uyan bir nesne hiyerarşisinde değildir. İlişkili olmayan sistemlerin parçası olan sınıflarla çalışıyor olabilirsiniz.
  • Eklediğiniz işlevsellik, bu sınıflar için temel soyutlamanın bir parçası değildir. Bir araç tarafından ödenen geçiş ücreti farklı araç türleri için değişir , ancak geçiş ücreti aracın temel işlevi değildir.

Verilerin şekli ve bu verilerdeki işlemler birlikte açıklanmamışsa, C# dilindeki desen eşleştirme özellikleri ile çalışmayı kolaylaştırır.

Temel geçiş ücreti hesaplamalarını uygula

En temel ücretli hesaplama yalnızca araç türüne bağlıdır:

  • Bir Car 2,00 dolardır.
  • Taxi 3,50 dolar.
  • A Bus 5,00 ABD doları.
  • A DeliveryTruck 10,00 ABD dolarıdır

Yeni TollCalculator sınıf oluşturun ve geçiş ücretini almak için araç türüne göre kalıp eşleştirme uygulayın. Aşağıdaki kod, TollCalculator'nin ilk uygulamasını gösterir.

using System;
using CommercialRegistration;
using ConsumerVehicleRegistration;
using LiveryRegistration;

namespace Calculators;

public class TollCalculator
{
    public decimal CalculateToll(object vehicle) =>
        vehicle switch
    {
        Car c           => 2.00m,
        Taxi t          => 3.50m,
        Bus b           => 5.00m,
        DeliveryTruck t => 10.00m,
        { }             => throw new ArgumentException(message: "Not a known vehicle type", paramName: nameof(vehicle)),
        null            => throw new ArgumentNullException(nameof(vehicle))
    };
}

Yukarıdaki kod, bildirim desenini test eden bir switch ifade (bu, switch deyimi ile aynı değildir) kullanır. Switch ifadesi önceki kodda vehicle değişkeniyle başlar ve ardından switch anahtar sözcüğü gelir. Ardından, süslü parantezlerin içinde yer alan tüm anahtar kollar geliyor. switch ifadesi, switch deyimini çevreleyen söz diziminde başka iyileştirmeler yapar. case anahtar sözcüğü atlanır ve her bir kolun sonucu bir ifadedir. Son iki kol, yeni bir dil özelliğini sergiliyor. { } durumu, önceki bir kolla eşleşmeyen boş olmayan herhangi bir nesneyle eşleşir. Bu kol, bu yönteme geçirilen yanlış türleri yakalar. { } durumu, her araç tipi için belirlenen durumların ardından gelmelidir. Durum tersine çevrilirse, { } öncelikli olacaktır. Son olarak, nullsabit desen bu yönteme ne zaman null geçirildiğini algılar. null deseni son olabilir çünkü diğer desenler yalnızca doğru türdeki null olmayan bir nesneyle eşleşir.

Aşağıdaki kodu Program.cs içinde kullanarak bu kodu test edebilirsiniz.

using System;
using CommercialRegistration;
using ConsumerVehicleRegistration;
using LiveryRegistration;

using toll_calculator;

var tollCalc = new TollCalculator();

var car = new Car();
var taxi = new Taxi();
var bus = new Bus();
var truck = new DeliveryTruck();

Console.WriteLine($"The toll for a car is {tollCalc.CalculateToll(car)}");
Console.WriteLine($"The toll for a taxi is {tollCalc.CalculateToll(taxi)}");
Console.WriteLine($"The toll for a bus is {tollCalc.CalculateToll(bus)}");
Console.WriteLine($"The toll for a truck is {tollCalc.CalculateToll(truck)}");

try
{
    tollCalc.CalculateToll("this will fail");
}
catch (ArgumentException e)
{
    Console.WriteLine("Caught an argument exception when using the wrong type");
}
try
{
    tollCalc.CalculateToll(null!);
}
catch (ArgumentNullException e)
{
    Console.WriteLine("Caught an argument exception when using null");
}

Bu kod başlangıç projesine dahil edilmiştir, ancak yorum satırı olarak eklenmiştir. Yorumları kaldırırsanız yazdıklarınızı test edebilirsiniz.

Desenlerin, kodun ve verilerin ayrı olduğu algoritmalar oluşturmanıza nasıl yardımcı olabileceğini görmeye başlıyorsunuz. switch ifadesi türü test eder ve sonuçlara göre farklı değerler üretir. Bu sadece başlangıç.

Doluluk fiyatlandırmasını ekle

Geçiş ücreti yetkilisi, araçların maksimum kapasitede seyahat etmesini teşvik etmek istiyor. Araçlar daha az yolcuya sahip olduğunda daha fazla ücret ödemeye ve daha düşük fiyatlandırma sunarak tam araçları teşvik etmeye karar verdiler:

  • Yolcu olmayan arabalar ve taksiler fazladan 0,50 dolar ödüyor.
  • İki yolcusu olan araba ve taksiler 0,50 ABD doları indirimden alır.
  • Üç veya daha fazla yolcusu olan araba ve taksiler 1,00 ABD doları indirimden alır.
  • %50 dolu değilse otobüsler ekstra 2,00 dolar ücret öder.
  • %90'dan fazla dolu otobüsler 1,00 ABD doları indirim alır.

Bu kurallar, aynı anahtar ifadesindeki bir özellik deseni kullanılarak uygulanabilir. Özellik deseni, bir özellik değerini sabit bir değerle karşılaştırır. Özellik düzeni, tür belirlendikten sonra nesnenin özelliklerini inceler. Car için tek bir durum dört farklı duruma genişler:

vehicle switch
{
    Car {Passengers: 0} => 2.00m + 0.50m,
    Car {Passengers: 1} => 2.0m,
    Car {Passengers: 2} => 2.0m - 0.50m,
    Car                 => 2.00m - 1.0m,

    // ...
};

İlk üç örnek türün Car olup olmadığını test eder ve ardından Passengers özelliğinin değerini kontrol eder. Her ikisi de eşleşirse, bu ifade değerlendirilir ve döndürülür.

Taksi ile ilgili durumları da benzer şekilde genişletirsiniz.

vehicle switch
{
    // ...

    Taxi {Fares: 0}  => 3.50m + 1.00m,
    Taxi {Fares: 1}  => 3.50m,
    Taxi {Fares: 2}  => 3.50m - 0.50m,
    Taxi             => 3.50m - 1.00m,

    // ...
};

Ardından, aşağıdaki örnekte gösterildiği gibi, otobüsler için durumları genişleterek doluluk kurallarını uygulayın.

vehicle switch
{
    // ...

    Bus b when ((double)b.Riders / (double)b.Capacity) < 0.50 => 5.00m + 2.00m,
    Bus b when ((double)b.Riders / (double)b.Capacity) > 0.90 => 5.00m - 1.00m,
    Bus => 5.00m,

    // ...
};

Geçiş ücreti yetkilisi, teslimat kamyonlarındaki yolcu sayısıyla ilgili değildir. Bunun yerine, kamyonların ağırlık sınıfına göre ücretli miktarı aşağıdaki gibi ayarlar:

  • 5000 lbs'nin üzerindeki kamyonlar fazladan 5,00 ABD doları ücretlendirilir.
  • 3000 lbs'nin altındaki hafif kamyonlara 2,00 ABD doları indirim verilir.

Bu kural aşağıdaki kodla uygulanır:

vehicle switch
{
    // ...

    DeliveryTruck t when (t.GrossWeightClass > 5000) => 10.00m + 5.00m,
    DeliveryTruck t when (t.GrossWeightClass < 3000) => 10.00m - 2.00m,
    DeliveryTruck => 10.00m,
};

Önceki kod, bir switch kolunun when yan tümcesini gösterir. Eşitlik dışında koşulları test etmek için when yan tümcesini kullanırsınız. İşiniz bittiğinde aşağıdaki koda çok benzeyen bir yönteminiz olur:

vehicle switch
{
    Car {Passengers: 0}        => 2.00m + 0.50m,
    Car {Passengers: 1}        => 2.0m,
    Car {Passengers: 2}        => 2.0m - 0.50m,
    Car                        => 2.00m - 1.0m,

    Taxi {Fares: 0}  => 3.50m + 1.00m,
    Taxi {Fares: 1}  => 3.50m,
    Taxi {Fares: 2}  => 3.50m - 0.50m,
    Taxi             => 3.50m - 1.00m,

    Bus b when ((double)b.Riders / (double)b.Capacity) < 0.50 => 5.00m + 2.00m,
    Bus b when ((double)b.Riders / (double)b.Capacity) > 0.90 => 5.00m - 1.00m,
    Bus => 5.00m,

    DeliveryTruck t when (t.GrossWeightClass > 5000) => 10.00m + 5.00m,
    DeliveryTruck t when (t.GrossWeightClass < 3000) => 10.00m - 2.00m,
    DeliveryTruck => 10.00m,

    { }     => throw new ArgumentException(message: "Not a known vehicle type", paramName: nameof(vehicle)),
    null    => throw new ArgumentNullException(nameof(vehicle))
};

Bu anahtar kollarının çoğu özyinelemeli desenlere örnektir. Örneğin, Car { Passengers: 1} bir özellik deseni içinde sabit bir desen gösterir.

İç içe anahtarlar kullanarak bu kodu daha az yinelenen hale getirebilirsiniz. Car ve Taxi, her ikisi de önceki örneklerde dört farklı kola sahiptir. Her iki durumda da, sabit bir desene beslenen bir bildirim deseni oluşturabilirsiniz. Bu teknik aşağıdaki kodda gösterilmiştir:

public decimal CalculateToll(object vehicle) =>
    vehicle switch
    {
        Car c => c.Passengers switch
        {
            0 => 2.00m + 0.5m,
            1 => 2.0m,
            2 => 2.0m - 0.5m,
            _ => 2.00m - 1.0m
        },

        Taxi t => t.Fares switch
        {
            0 => 3.50m + 1.00m,
            1 => 3.50m,
            2 => 3.50m - 0.50m,
            _ => 3.50m - 1.00m
        },

        Bus b when ((double)b.Riders / (double)b.Capacity) < 0.50 => 5.00m + 2.00m,
        Bus b when ((double)b.Riders / (double)b.Capacity) > 0.90 => 5.00m - 1.00m,
        Bus b => 5.00m,

        DeliveryTruck t when (t.GrossWeightClass > 5000) => 10.00m + 5.00m,
        DeliveryTruck t when (t.GrossWeightClass < 3000) => 10.00m - 2.00m,
        DeliveryTruck t => 10.00m,

        { }  => throw new ArgumentException(message: "Not a known vehicle type", paramName: nameof(vehicle)),
        null => throw new ArgumentNullException(nameof(vehicle))
    };

Önceki örnekte, özyinelemeli bir ifade kullanmak, özellik değerini test eden alt kolları içeren Car ve Taxi kollarını tekrar etmemeniz anlamına gelir. Bu teknik, Bus ve DeliveryTruck kolları için kullanılmaz çünkü bu kollar, ayrık değerler yerine özelliğin aralıklarını test etmektedir.

En yüksek fiyatlandırmayı ekleme

Son özellik için geçiş ücreti yetkilisi, zamana duyarlı yoğun saat fiyatlandırması eklemek istiyor. Sabah ve akşam yoğun saatlerde, geçiş ücretleri iki katına alınır. Bu kural trafiği yalnızca bir yönde etkiler: sabah şehre gelen ve akşam yoğun saatlerde giden. İş günü boyunca diğer zamanlarda, geçiş ücretleri % 50 artar. Gece geç saatlerde ve sabahın erken saatlerinde geçiş ücretleri %25 azaltılır. Hafta sonu boyunca, saat ne olursa olsun normal fiyattır. Aşağıdaki kodu kullanarak bunu ifade etmek için bir dizi if ve else deyimi kullanabilirsiniz:

public decimal PeakTimePremiumIfElse(DateTime timeOfToll, bool inbound)
{
    if ((timeOfToll.DayOfWeek == DayOfWeek.Saturday) ||
        (timeOfToll.DayOfWeek == DayOfWeek.Sunday))
    {
        return 1.0m;
    }
    else
    {
        int hour = timeOfToll.Hour;
        if (hour < 6)
        {
            return 0.75m;
        }
        else if (hour < 10)
        {
            if (inbound)
            {
                return 2.0m;
            }
            else
            {
                return 1.0m;
            }
        }
        else if (hour < 16)
        {
            return 1.5m;
        }
        else if (hour < 20)
        {
            if (inbound)
            {
                return 1.0m;
            }
            else
            {
                return 2.0m;
            }
        }
        else // Overnight
        {
            return 0.75m;
        }
    }
}

Yukarıdaki kod düzgün çalışıyor, ancak okunamıyor. Tüm giriş durumlarını ve iç içe geçmiş if deyimlerini birleştirerek kod hakkında düşünmeniz gerekir. Bunun yerine, bu özellik için desen eşleştirmeyi kullanacaksınız, ancak bunu diğer tekniklerle tümleştireceksiniz. Yönün, haftanın gününün ve saatin tüm birleşimlerini hesaplayan tek bir desen eşleştirme ifadesi oluşturabilirsiniz. Sonuç karmaşık bir ifade olacaktır. Okuması zor ve anlaşılması zor olurdu. Bu, doğruluğu sağlamayı zorlaştırır. Bunun yerine, tüm bu durumları kısa bir şekilde açıklayan bir değer tanımlama grubu oluşturmak için bu yöntemleri birleştirin. Ardından, geçiş ücretinin çarpanını hesaplamak için desen eşleştirmeyi kullanın. Üç ayrı koşul içeren bir dizi.

  • Gün hafta içi veya hafta sonudur.
  • Ücretin toplandığı zaman dilimi.
  • Yön şehir merkezi veya şehir dışına doğru

Aşağıdaki tabloda giriş değerlerinin birleşimleri ve en yüksek fiyatlandırma çarpanı gösterilmektedir:

Gün Zaman Yön Üst Düzey
Hafta içi sabah acelesi gelen x 2,00
Hafta içi sabah acelesi dışa giden x 1,00
Hafta içi gündüz gelen x 1,50
Hafta içi gündüz dışa giden x 1,50
Hafta içi akşam trafiği gelen x 1,00
Hafta içi akşam trafiği dışa giden x 2,00
Hafta içi geceleyin gelen x 0,75
Hafta içi geceleyin dışa giden x 0,75
Hafta Sonu sabah acelesi gelen x 1,00
Hafta Sonu sabah acelesi dışa giden x 1,00
Hafta Sonu gündüz gelen x 1,00
Hafta Sonu gündüz dışa giden x 1,00
Hafta Sonu akşam trafiği gelen x 1,00
Hafta Sonu akşam trafiği dışa giden x 1,00
Hafta Sonu geceleyin gelen x 1,00
Hafta Sonu geceleyin dışa giden x 1,00

Üç değişkenin 16 farklı bileşimi vardır. Bazı koşulları birleştirerek son anahtar ifadesini basitleştireceksiniz.

Geçiş ücretlerini toplayan sistem, ücretin toplandığı zaman için bir DateTime yapı kullanır. Önceki tablodan değişkenleri oluşturan üye yöntemleri oluşturun. Aşağıdaki işlev, DateTime'nin bir hafta sonunu mu yoksa hafta içi gününü mü temsil ettiğini ifade etmek için desen eşleştirme anahtar ifadesi kullanır.

private static bool IsWeekDay(DateTime timeOfToll) =>
    timeOfToll.DayOfWeek switch
    {
        DayOfWeek.Monday    => true,
        DayOfWeek.Tuesday   => true,
        DayOfWeek.Wednesday => true,
        DayOfWeek.Thursday  => true,
        DayOfWeek.Friday    => true,
        DayOfWeek.Saturday  => false,
        DayOfWeek.Sunday    => false
    };

Bu yöntem doğrudur, ancak yineleniyor. Aşağıdaki kodda gösterildiği gibi basitleştirebilirsiniz:

private static bool IsWeekDay(DateTime timeOfToll) =>
    timeOfToll.DayOfWeek switch
    {
        DayOfWeek.Saturday => false,
        DayOfWeek.Sunday => false,
        _ => true
    };

Ardından, zamanı bloklara kategorilere ayırmak için benzer bir işlev ekleyin:

private enum TimeBand
{
    MorningRush,
    Daytime,
    EveningRush,
    Overnight
}

private static TimeBand GetTimeBand(DateTime timeOfToll) =>
    timeOfToll.Hour switch
    {
        < 6 or > 19 => TimeBand.Overnight,
        < 10 => TimeBand.MorningRush,
        < 16 => TimeBand.Daytime,
        _ => TimeBand.EveningRush,
    };

Her zaman aralığını ayrık bir değere dönüştürmek için özel enum eklersiniz. Ardından GetTimeBand yöntemi, ilişkisel desenler ve konjonktif desenler kullanır. İlişkisel desen, , , <>veya <=kullanarak >=sayısal bir değeri test etmenizi sağlar. Desen, or bir ifadenin bir veya daha fazla desenle eşleşip eşleşmediğini test eder. Ayrıca, bir and ifadenin iki ayrı desenle eşleştiğinden emin olmak için bir desen ve bir ifadenin bir not desenle eşleşmediğini test etmek için bir desen de kullanabilirsiniz.

Bu yöntemleri oluşturduktan sonra, fiyat farkını hesaplamak için switch başka bir ifade kullanabilirsiniz. 16 kolu olan bir switch ifade oluşturabilirsiniz:

public decimal PeakTimePremiumFull(DateTime timeOfToll, bool inbound) =>
    (IsWeekDay(timeOfToll), GetTimeBand(timeOfToll), inbound) switch
    {
        (true, TimeBand.MorningRush, true) => 2.00m,
        (true, TimeBand.MorningRush, false) => 1.00m,
        (true, TimeBand.Daytime, true) => 1.50m,
        (true, TimeBand.Daytime, false) => 1.50m,
        (true, TimeBand.EveningRush, true) => 1.00m,
        (true, TimeBand.EveningRush, false) => 2.00m,
        (true, TimeBand.Overnight, true) => 0.75m,
        (true, TimeBand.Overnight, false) => 0.75m,
        (false, TimeBand.MorningRush, true) => 1.00m,
        (false, TimeBand.MorningRush, false) => 1.00m,
        (false, TimeBand.Daytime, true) => 1.00m,
        (false, TimeBand.Daytime, false) => 1.00m,
        (false, TimeBand.EveningRush, true) => 1.00m,
        (false, TimeBand.EveningRush, false) => 1.00m,
        (false, TimeBand.Overnight, true) => 1.00m,
        (false, TimeBand.Overnight, false) => 1.00m,
    };

Yukarıdaki kod çalışır, ancak basitleştirilebilir. Hafta sonu için sekiz kombinasyon da aynı geçiş ücretine sahip. Sekizini de aşağıdaki satırla değiştirebilirsiniz:

(false, _, _) => 1.0m,

Hem gelen hem de giden trafik, hafta içi gündüz ve gece saatlerinde aynı çarpana sahiptir. Bu dört anahtar kolu aşağıdaki iki satırla değiştirilebilir:

(true, TimeBand.Overnight, _) => 0.75m,
(true, TimeBand.Daytime, _)   => 1.5m,

Bu iki değişiklik sonrasında kod aşağıdaki kod gibi görünmelidir:

public decimal PeakTimePremium(DateTime timeOfToll, bool inbound) =>
    (IsWeekDay(timeOfToll), GetTimeBand(timeOfToll), inbound) switch
    {
        (true, TimeBand.MorningRush, true)  => 2.00m,
        (true, TimeBand.MorningRush, false) => 1.00m,
        (true, TimeBand.Daytime,     _)     => 1.50m,
        (true, TimeBand.EveningRush, true)  => 1.00m,
        (true, TimeBand.EveningRush, false) => 2.00m,
        (true, TimeBand.Overnight,   _)     => 0.75m,
        (false, _,                   _)     => 1.00m,
    };

Son olarak, standart fiyatla ücretlendirilen iki yoğun saati kaldırabilirsiniz. Bu kolları çıkardıktan sonra, son switch kolundaki false diskard (_) ile değiştirebilirsiniz. Aşağıdaki tamamlanmış yönteminiz olacaktır:

public decimal PeakTimePremium(DateTime timeOfToll, bool inbound) =>
    (IsWeekDay(timeOfToll), GetTimeBand(timeOfToll), inbound) switch
    {
        (true, TimeBand.Overnight, _) => 0.75m,
        (true, TimeBand.Daytime, _) => 1.5m,
        (true, TimeBand.MorningRush, true) => 2.0m,
        (true, TimeBand.EveningRush, false) => 2.0m,
        _ => 1.0m,
    };

Bu örnek, desen eşleştirmenin avantajlarından birini vurgular: desen dalları sırayla değerlendirilir. Önceki bir dalın sonraki durumlarınızdan birini işlemesi için bunları yeniden düzenlerseniz, derleyici ulaşılamayan kod hakkında sizi uyarır. Bu dil kuralları, önceki basitleştirmeleri kodun değişmediğinden güvenle yapmayı kolaylaştırdı.

Desen eşleştirme, bazı kod türlerini daha okunabilir hale getirir ve sınıflarınıza kod ekleyemiyorsanız nesne odaklı tekniklere alternatif sunar. Bulut, verilerin ve işlevlerin birbirinden ayrı yaşamasına neden oluyor. Verilerin şekli ve üzerindeki işlemler birlikte açıklanmamıştır. Bu öğreticide, mevcut verileri özgün işlevinden tamamen farklı şekillerde kullandınız. Desen eşleştirme, bu türleri genişletemeseniz bile bu türleri aşan işlevler yazmanızı sağlar.

Sonraki adımlar

Tamamlanmış kodu dotnet/samples GitHub deposundan indirebilirsiniz. Desenleri kendi başınıza keşfedin ve bu tekniği normal kodlama etkinliklerinize ekleyin. Bu teknikleri öğrenmek, sorunlara yaklaşmanın ve yeni işlevler oluşturmanın başka bir yolunu sunar.

Ayrıca bkz.