Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A mintailesztés lehetővé teszi funkciók hozzáadását a más kódtárakban definiált típusokhoz anélkül, hogy módosítaná ezeket a típusokat. A minták másik funkciója, hogy olyan funkciókat hozzon létre, amelyeket az alkalmazás igényel, és ez nem a kibővítendő típus alapvető funkciója.
Ebben az oktatóanyagban a következőket sajátíthatja el:
- Felismerhet olyan helyzeteket, amikor mintaegyezést kell használni.
- Mintamegfeleltetési kifejezések használatával típusok és tulajdonságértékek alapján valósíthat meg viselkedést.
- A mintaegyeztetés más technikákkal kombinálva teljes algoritmusokat hozhat létre.
Prerequisites
- A legújabb .NET SDK
- Visual Studio Code szerkesztő
- A C# fejlesztőkészlet
Telepítési utasítások
Ez a WinGet konfigurációs fájl használható a Windows rendszerben az összes előfeltétel telepítéséhez. Ha már telepített valamit, a WinGet kihagyja ezt a lépést.
- Töltse le a fájlt, és kattintson rá duplán a futtatáshoz.
- Olvassa el a licencszerződést, írja be y, és válassza Adja meg, amikor a rendszer kéri az elfogadást.
- Ha a tálcán megjelenik egy villogó Felhasználói fiókok felügyelete (UAC) kérés, engedélyezze a telepítés folytatását.
Más platformokon külön kell telepítenie ezeket az összetevőket.
- Töltse le az ajánlott telepítőt a .NET SDK letöltési oldaláról és kattintson rá duplán a futtatásához. A letöltési oldal észleli a platformot, és a legújabb telepítőt javasolja a platformhoz.
- Töltse le a legújabb telepítőt a Visual Studio Code kezdőlapjáról, és kattintson duplán a futtatáshoz. Ez az oldal a platformot is észleli, és a hivatkozásnak helyesnek kell lennie a rendszer számára.
- Kattintson a "Telepítés" gombra a C# DevKit bővítménylapon. Ez megnyitja a Visual Studio-kódot, és megkérdezi, hogy szeretné-e telepíteni vagy engedélyezni a bővítményt. Válassza a "telepítés" lehetőséget.
Forgatókönyvek mintaegyeztetéshez
A modern fejlesztés gyakran magában foglalja több forrásból származó adatok integrálását, valamint az adatokból származó információk és megállapítások egyetlen összetartó alkalmazásban való bemutatását. Előfordulhat, hogy Ön és csapata nem szabályozza a bejövő adatokat képviselő típusokat.
A klasszikus objektumorientált tervezési megközelítés megköveteli olyan típusok létrehozását az alkalmazásban, amelyek az egyes, azokból a többféle adatforrásokból származó adattípusokat képviselik. Ezután az alkalmazás együttműködik ezekkel az új típusokkal, öröklési hierarchiákat hoz létre, virtuális metódusokat hoz létre, és absztrakciókat valósít meg. Ezek a technikák működnek, és néha ezek a legjobb eszközök. Máskor kevesebb kódot írhat. Bizonyos esetekben az adatoknak az azokat használó műveletektől való elkülönítése könnyebben olvashatóvá teheti a kódot.
Ebben az oktatóanyagban létrehoz és megvizsgál egy olyan alkalmazást, amely egyetlen forgatókönyvhöz több külső forrásból érkező adatokat fogad. Láthatja, hogy a mintaegyeztetés hogyan biztosít hatékony módot az adatok felhasználására és feldolgozására olyan módokon, amelyek nem voltak részei az eredeti rendszernek.
Vegyünk egy nagyobb nagyvárosi területet, amely útdíjakat és csúcsidő-díjszabást használ a forgalom kezeléséhez. Olyan alkalmazást ír, amely a típusától függően számítja ki a járművek útdíjait. A későbbi fejlesztések a járműben tartózkodók száma alapján tartalmazzák a díjszabást. A további fejlesztések a hét ideje és napja alapján adnak hozzá díjszabást.
Ebből a rövid leírásból gyorsan felvázolhat egy objektumhierarchiát a rendszer modellezéséhez. Az adatok azonban több forrásból származnak, például más járműnyilvántartás-kezelő rendszerekből. Ezek a rendszerek különböző osztályokat biztosítanak az adatok modellezéséhez, és ezek a rendszerek nem rendelkeznek egyetlen objektummodellel. Ebben az oktatóanyagban ezeket az egyszerűsített osztályokat használja a külső rendszerek járműadatainak modellezésére, ahogyan az a következő kódban is látható:
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; }
}
}
A kezdőkódot a dotnet/samples GitHub-adattárból töltheti le. Láthatja, hogy a járműosztályok különböző rendszerekből származnak, és különböző névterekben vannak. Nem használhat a(z) System.Object-n kívül más közös alaposztályt.
Mintaillesztési tervek
Az oktatóanyagban használt forgatókönyv kiemeli azokat a problémákat, amelyeket a mintaegyezés jól megold:
- A használni kívánt objektumok nem a céljainak megfelelő objektumhierarchiában szerepelnek. Előfordulhat, hogy egymással nem összefüggő rendszerekhez tartozó osztályokkal dolgozik.
- A hozzáadott funkciók nem részei ezeknek az osztályoknak az alapvető absztrakciójának. A jármű által fizetett útdíj különböző típusú járművek esetében változik , de az útdíj nem a jármű alapvető funkciója.
Ha az adatok alakját és az adatokon végzett műveleteket nem írják le együtt, a C# mintamegfeleltetési funkciói megkönnyítik a munkát.
Az alapszintű útdíjszámítások implementálása
A legalapvetőbb díjszámítás csak a járműtípusra támaszkodik:
- A
Car2,00 dollár. - A
Taxi3,50 dollár. - Egy
Bus5,00 dollár. - A
DeliveryTruckára 10,00 dollár.
Hozzon létre egy új TollCalculator osztályt, és alkalmazza a mintafelismerést a jármű típusán az útdíj összegének meghatározásához. A következő kód bemutatja a TollCalculator kezdeti megvalósítását.
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))
};
}
Az előző kód egy switch olyan kifejezést használ (nem ugyanaz, mint egy switch utasítás), amely teszteli a deklarációs mintát. A kapcsolókifejezés a változóval kezdődik az vehicle előző kódban, amelyet a switch kulcsszó követ. Ezután jön az összes kapcsolókar a kapcsos zárójelek között. A switch kifejezés további pontosításokat végez a switch utasítást körülvevő szintaxisra. A case kulcsszó nincs megadva, és az egyes karok eredménye egy kifejezés. Az utolsó két kar egy új nyelvi funkciót mutat be. Az { } eset minden olyan nem null értékű objektummal egyezik meg, amely nem egyezett meg egy korábbi ággal. Ez a kar elkapja a metódusnak átadott helytelen típusokat. Az { } esetnek az egyes járműtípusokra vonatkozó eseteket kell követnie. A sorrend megfordítása esetén az { } eset elsőbbséget élvezne. Végül az nullállandó minta észleli, amikor null kerül a metódusba. A null minta lehet utolsó, mert a többi minta csak a megfelelő típusú nem null objektumnak felel meg.
Ezt a kódot a következő kóddal Program.cstesztelheti:
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");
}
Ez a kód szerepel a kezdőprojektben, de ki van kommentezve. Távolítsa el a megjegyzéseket, és tesztelje, hogy mit írt.
Elkezdi látni, hogyan segíthetnek a minták olyan algoritmusok létrehozásában, amelyekben a kód és az adatok külön vannak. A switch kifejezés teszteli a típust, és az eredmények alapján különböző értékeket hoz létre. Ez csak a kezdet.
Foglaltsági díjszabás hozzáadása
Az útdíjügyi hatóság arra szeretné ösztönözni a járműveket, hogy maximális kapacitással utazzanak. Úgy döntenek, hogy többet számolnak fel, ha a járművek kevesebb utassal rendelkeznek, és alacsonyabb díjszabással ösztönzik a tele járművek használatát:
- Az utasok nélküli autók és taxik további 0,50 dollárt fizetnek.
- A két utassal rendelkező autók és taxik 0,50 dolláros kedvezményt kapnak.
- A három vagy több utassal rendelkező autók és taxik 1,00 usd kedvezményt kapnak.
- Azok az autóbuszok, amelyek kevesebb mint 50%-ban telítettek, további 2,00 USD-t fizetnek.
- A több mint 90%-ban megtelt buszok 1,00 usd kedvezményt kapnak.
Ezeket a szabályokat ugyanabban a switch-kifejezésben egy property pattern használatával implementálhatja. A tulajdonságminta egy tulajdonság értékét egy állandó értékkel hasonlítja össze. A tulajdonságminta a típus meghatározása után megvizsgálja az objektum tulajdonságait.
Car {Passengers: 0} maga is egy rekurzív mintaillesztés: a külső tulajdonságminta Car egy belső állandó mintát tartalmaz, amely teszteli az Passengers értéket. A Car egyetlen esete négy különböző esetre bővül.
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,
// ...
};
Az első három esetben tesztelik a típust Car, majd ellenőrzik a Passengers tulajdonság értékét. Ha mindkettő egyezik, a kifejezés kiértékelődik, és értéket ad vissza.
A taxis eseteket is hasonló módon bővítheti:
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,
// ...
};
Ezután hajtsa végre a bérlői szabályokat a buszokra vonatkozó esetek kibővítésével, ahogyan az alábbi példában látható:
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,
// ...
};
Az útdíjszolgáltató nem foglalkozik a szállító teherautók utasainak számával. Ehelyett az útdíj összegét a teherautók súlyosztálya alapján az alábbiak szerint módosítják:
- Az 5000 lbs feletti teherautókért további 5,00 usd díjat számítunk fel.
- A 3000 lbs alatti könnyű teherautók 2,00 usd kedvezményt kapnak.
Ezt a szabályt a következő kóddal implementálhatja:
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,
};
Az előző kód egy when kapcsolókar záradékát mutatja. A záradék használatával tesztelje egy tulajdonságon az egyenlőségtől eltérő feltételeket. Amikor végzett, egy olyan metódussal rendelkezik, amely az alábbi kódhoz hasonlóan néz ki:
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))
};
Ahogy korábban említettük, ezek a switch-ágak rekurzív minták, amelyek egy konstans mintát ágyaznak be egy tulajdonságmintába.
Ezt a kódot kevésbé ismétlődővé teheti beágyazott kapcsolók használatával. A Car és a Taxi egyaránt négy különböző karral rendelkezik az előző példákban. Mindkét esetben létrehozhat egy deklarációs mintát, amely egy állandó mintává alakul át. Ez a technika a következő kódban jelenik meg:
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))
};
Az előző példában egy switch kifejezés beágyazása egy másik switch-ágba azt jelenti, hogy nem kell megismételni a Car és Taxi ágakat, amelyek a tulajdonság értékét vizsgáló beágyazott ágakat tartalmazzák. Ezt a technikát nem használják a DeliveryTruck és Bus ágak esetében, mert ezek az ágak a tulajdonság értéktartományait tesztelik, nem diszkrét értékeket.
Adja hozzá a csúcsárakat
Utolsó funkcióként az útdíjszolgáltató időérzékeny csúcsidős díjszabást szeretne hozzáadni. A reggeli és az esti csúcsidőben az útdíjak megduplázódnak. Ez a szabály csak egy irányban befolyásolja a forgalmat: reggel befelé a városba, és kifelé az esti csúcsidőben. A munkanap más időszakaiban az útdíjak 50%-kal növekednek. Késő este és kora reggel az útdíj 25%-kal csökken. A hétvégén ez a normál ráta, az időtől függetlenül. A szabályt a következő kóddal, if és else utasítások sorozatával fejezheti ki:
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;
}
}
}
Az előző kód megfelelően működik, de nem olvasható. Az összes bemeneti esetet és a beágyazott if utasításokat láncra kell fűznie, hogy átláthassa a kódot. Ehelyett mintaillesztést fog használni ehhez a funkcióhoz, de más technikákkal is integrálni fogja. Létrehozhat egyetlen mintaegyeztetési kifejezést, amely figyelembe veszi az irány, a hét napja és az idő összes kombinációját. Az eredmény egy bonyolult kifejezés lenne. Nehéz lenne olvasni és nehéz megérteni. Ez megnehezíti a helyesség biztosítását. Ehelyett kombinálja ezeket a módszereket, hogy olyan értékeket hozzon létre, amelyek tömören ismertetik ezeket az állapotokat. Ezután használja a mintaegyezést az útdíj szorzójának kiszámításához. A n-tupla három különálló feltételt tartalmaz:
- A nap egy hétköznap vagy egy hétvége.
- Az útdíj beszedésének idősávja.
- Az irány a városba vagy a városból kifelé vezet.
Az alábbi táblázat a bemeneti értékek és a csúcsdíj-szorzó kombinációit mutatja be:
| Nap | Idő | Direction | prémium |
|---|---|---|---|
| Hétköznap | reggeli rohanás | inbound | x 2,00 |
| Hétköznap | reggeli rohanás | outbound | x 1,00 |
| Hétköznap | nappali | inbound | x 1,50 |
| Hétköznap | nappali | outbound | x 1,50 |
| Hétköznap | esti csúcsforgalom | inbound | x 1,00 |
| Hétköznap | esti csúcsforgalom | outbound | x 2,00 |
| Hétköznap | előző éjjel | inbound | x 0,75 |
| Hétköznap | előző éjjel | outbound | x 0,75 |
| Hétvége | reggeli rohanás | inbound | x 1,00 |
| Hétvége | reggeli rohanás | outbound | x 1,00 |
| Hétvége | nappali | inbound | x 1,00 |
| Hétvége | nappali | outbound | x 1,00 |
| Hétvége | esti csúcsforgalom | inbound | x 1,00 |
| Hétvége | esti csúcsforgalom | outbound | x 1,00 |
| Hétvége | előző éjjel | inbound | x 1,00 |
| Hétvége | előző éjjel | outbound | x 1,00 |
A három változónak 16 különböző kombinációja van. Néhány feltétel kombinálásával egyszerűsítheti a végső kapcsolókifejezést.
Az útdíjakat gyűjtő rendszer egy struktúrát DateTime használ az útdíj beszedésének idejére. Készíts tagfüggvényeket, amelyek létrehozzák az előző tábla változóit. Az alábbi függvény egy mintaegyező kapcsolókifejezéssel fejezi ki, hogy egy DateTime hétvége vagy egy hétköznap van-e:
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
};
Ez a módszer helyes, de ismétlődő. Egyszerűsítheti azt, ahogy az a következő kódban is látható:
private static bool IsWeekDay(DateTime timeOfToll) =>
timeOfToll.DayOfWeek switch
{
DayOfWeek.Saturday => false,
DayOfWeek.Sunday => false,
_ => true
};
Ezután adjon hozzá egy hasonló függvényt, amely kategorizálja az időt a blokkokba:
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,
};
Adjon hozzá egy privát enum értéket az egyes időtartományok különálló értékké alakításához. Ezután a GetTimeBand metódus relációs mintákat és logikai mintákat használ. A relációs minta lehetővé teszi egy számérték tesztelését a <, >, <= vagy >= használatával. A logikai minták más mintákat kombinálnak: egy or minta azt teszteli, hogy egy kifejezés egy vagy több mintára illeszkedik, egy and minta azt teszteli, hogy egy kifejezés két különböző mintára illeszkedik, egy not minta pedig azt teszteli, hogy egy kifejezés nem illeszkedik egy mintára.
Miután létrehozta ezeket a metódusokat, használhat egy másik switch kifejezést tuple mintával – egy olyan pozíciómintát, amely megfelel egy tuple egyes elemeinek – a tarifadíj kiszámításához. Létrehozhat egy switch kifejezést mind a 16 karral:
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,
};
Az előző kód működik, de egyszerűsíthető. Mind a nyolc kombinációnak ugyanaz az útdíj van a hétvégén. A nyolcat a következő sorra cserélheti:
(false, _, _) => 1.0m,
A bejövő és a kimenő forgalom is ugyanazt a szorzót használja a hétköznap napközben és az éjszakai órákban. Ezt a négy kapcsolókart a következő két sorral cserélheti le:
(true, TimeBand.Overnight, _) => 0.75m,
(true, TimeBand.Daytime, _) => 1.5m,
A kódnak a következő kódhoz hasonlóan kell kinéznie a két módosítás után:
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,
};
Végül távolítsa el a két csúcsidős időpontot, amelyekre a szokásos ár vonatkozik. Miután eltávolította ezeket a karokat, cserélje le a(z) false elemet egy eldobásra (_) az utolsó kapcsolókarban. A következő kész metódust kapja:
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,
};
Ez a példa a mintaegyeztetés egyik előnyét emeli ki: a mintaágak kiértékelése sorrendben történik. Ha úgy rendezi át őket, hogy egy korábbi ág kezelje az egyik későbbi esetet, a fordító figyelmezteti a nem elérhető kódra. Ezek a nyelvi szabályok egyszerűbbé tették az előző egyszerűsítéseket azzal a magabiztossággal, hogy a kód nem változott.
A mintaegyeztetés bizonyos kódtípusokat olvashatóbbá tesz, és alternatívát kínál az objektumorientált technikák helyett, ha nem tud kódot hozzáadni az osztályokhoz. A felhő miatt az adatok és a funkciók egymástól elkülönülnek. Az adatok alakját és a rajta lévő műveleteket nem feltétlenül írják le együtt. Ebben az oktatóanyagban a meglévő adatokat teljesen más módon használta fel, mint az eredeti céljának megfelelően. A mintamegfeleltetés lehetővé tette, hogy olyan funkciókat írjon, amelyek felülírják ezeket a típusokat, még akkor is, ha nem tudta kiterjeszteni őket.
További lépések
A kész kódot letöltheti a dotnet/samples GitHub-adattárból. Saját maga is megismerheti a mintákat, és hozzáadhatja ezt a technikát a szokásos kódolási tevékenységekhez. Ezeknek a technikáknak a elsajátítása lehetővé teszi a problémák megközelítését és új funkciók létrehozását.