Zelfstudie: Algoritmen bouwen met behulp van pattern matching

Met patroonovereenkomst kunt u functionaliteit toevoegen voor typen die zijn gedefinieerd in andere bibliotheken zonder deze typen te wijzigen. Een ander gebruik voor patronen is het maken van functionaliteit die uw toepassing vereist, dat is geen fundamentele functie van het type dat wordt uitgebreid.

In deze handleiding leer je hoe je:

  • Situaties herkennen waarin patroonkoppeling moet worden gebruikt.
  • Gebruik patroonkoppelingsexpressies om gedrag te implementeren op basis van typen en eigenschapswaarden.
  • Combineer patroonkoppeling met andere technieken om volledige algoritmen te maken.

Prerequisites

Installatie-instructies

Op Windows wordt dit WinGet-configuratiebestand gebruikt om alle vereisten te installeren. Als u al iets hebt geïnstalleerd, slaat WinGet die stap over.

  1. Download het bestand en dubbelklik erop om het uit te voeren.
  2. Lees de gebruiksrechtovereenkomst, typ yen selecteer Enter wanneer u wordt gevraagd om te accepteren.
  3. Als u een knipperende UAC-prompt (User Account Control) krijgt op de taakbalk, staat u de installatie toe om door te gaan.

Op andere platforms moet u elk van deze onderdelen afzonderlijk installeren.

  1. Download het aanbevolen installatieprogramma op de downloadpagina van de .NET SDK en dubbelklik erop om het uit te voeren. De downloadpagina detecteert uw platform en raadt het meest recente installatieprogramma voor uw platform aan.
  2. Download het meest recente installatieprogramma op de startpagina van Visual Studio Code en dubbelklik erop om het uit te voeren. Deze pagina detecteert ook uw platform en de koppeling moet juist zijn voor uw systeem.
  3. Klik op de knop Installeren op de pagina C# DevKit extensie. Hiermee wordt Visual Studio code geopend en wordt gevraagd of u de extensie wilt installeren of inschakelen. Selecteer 'installeren'.

Scenario's voor patroonkoppeling

Moderne ontwikkeling omvat vaak het integreren van gegevens uit meerdere bronnen en het presenteren van informatie en inzichten uit die gegevens in één samenhangende toepassing. U en uw team hebben mogelijk geen controle over de typen die binnenkomende gegevens vertegenwoordigen.

De klassieke objectgeoriënteerde ontwerpbenadering vraagt om typen in uw toepassing te maken die elk gegevenstype uit die meerdere gegevensbronnen vertegenwoordigen. Vervolgens werkt uw toepassing met deze nieuwe typen, bouwt overervingshiërarchieën, maakt u virtuele methoden en implementeert u abstracties. Deze technieken werken en soms zijn ze de beste hulpmiddelen. Andere keren kunt u minder code schrijven. In sommige gevallen kunnen gegevens worden gescheiden van de bewerkingen die deze gegevens gebruiken, waardoor de code gemakkelijker te lezen is.

In deze zelfstudie maakt en verkent u een toepassing die binnenkomende gegevens uit verschillende externe bronnen ontvangt voor één scenario. U ziet hoe patroonmatching een efficiënte manier biedt om die gegevens te gebruiken en te verwerken op manieren die niet deel uitmaakten van het oorspronkelijke systeem.

Overweeg een belangrijk grootstedelijk gebied dat tolgelden en piektijdprijzen gebruikt om verkeer te beheren. U schrijft een toepassing die tolgelden voor een voertuig berekent op basis van het type. Latere verbeteringen omvatten prijzen op basis van het aantal inzittenden in het voertuig. Verdere verbeteringen voegen prijzen toe op basis van de tijd en de dag van de week.

Vanuit die korte beschrijving kunt u snel een objecthiërarchie schetsen om dit systeem te modelleren. Uw gegevens zijn echter afkomstig uit meerdere bronnen, zoals andere systemen voor voertuigregistratiebeheer. Deze systemen bieden verschillende klassen om die gegevens te modelleren en die systemen delen geen enkel objectmodel. In deze zelfstudie gebruikt u deze vereenvoudigde klassen om de voertuiggegevens van deze externe systemen te modelleren, zoals wordt weergegeven in de volgende code:

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

U kunt de starterscode downloaden uit de GitHub-opslagplaats dotnet/samples . U kunt zien dat de voertuigklassen afkomstig zijn van verschillende systemen en zich in verschillende naamruimten bevinden. U kunt geen gemeenschappelijke basisklasse anders dan System.Object gebruiken.

Patronenherkenningsontwerpen

In het scenario dat in deze zelfstudie wordt gebruikt, worden de soorten problemen belicht die goed worden opgelost met patroonmatching:

  • De objecten waarmee u moet werken, zijn niet in een objecthiërarchie die overeenkomt met uw doelstellingen. Mogelijk werkt u met klassen die deel uitmaken van niet-gerelateerde systemen.
  • De functionaliteit die u toevoegt, maakt geen deel uit van de kernabstractie voor deze klassen. De tol die door een voertuig wordt betaald, verandert voor verschillende typen voertuigen, maar het tolgeld is geen kernfunctie van het voertuig.

Wanneer de vorm van de gegevens en de bewerkingen op die gegevens niet samen worden beschreven, maken de patroonkoppelingsfuncties in C# het gemakkelijker om mee te werken.

De basisberekeningen voor tol implementeren

De meest eenvoudige tolberekening is alleen afhankelijk van het voertuigtype:

  • Een Car is $ 2,00.
  • Een Taxi is $3,50.
  • A Bus is $ 5,00.
  • Een DeliveryTruck is $10,00.

Maak een nieuwe TollCalculator klasse en implementeer patroonkoppeling op het voertuigtype om het betaalde bedrag op te halen. De volgende code toont de eerste implementatie van de TollCalculator.

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

In de voorgaande code wordt een expressie (niet hetzelfde als een switch instructie) gebruikt waarmee het switch wordt getest. Een switchexpressie begint met de variabele, vehicle in de voorgaande code, gevolgd door het switch trefwoord. Vervolgens komen alle schakelarmen binnen accolades. De switch expressie maakt andere verfijningen aan de syntaxis rondom de switch verklaring. Het case trefwoord wordt weggelaten en het resultaat van elke arm is een expressie. De laatste twee armen tonen een nieuwe taalfunctie. De { } case komt overeen met een niet-null-object dat niet overeenkomt met een eerdere arm. Deze arm onderschept alle onjuiste typen die aan deze methode worden doorgegeven. De { } casus moet de gevallen voor elk voertuigtype respecteren. Als de volgorde werd omgekeerd, zou de { } zaak voorrang krijgen. Ten slotte detecteert het nullconstante patroon wanneer null aan deze methode wordt doorgegeven. Het null patroon kan het laatst zijn omdat de andere patronen alleen overeenkomen met een niet-null-object van het juiste type.

U kunt deze code testen met behulp van de volgende code in Program.cs:

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

Deze code is opgenomen in het startersproject, maar is uitgecommentarieerd. Verwijder de commentaartekens en u kunt testen wat u hebt geschreven.

U begint te zien hoe patronen u kunnen helpen bij het maken van algoritmen waarbij de code en de gegevens gescheiden zijn. De switch expressie test het type en produceert verschillende waarden op basis van de resultaten. Dat is alleen het begin.

Bezettingsprijzen toevoegen

De tolautoriteit wil voertuigen aanmoedigen om op maximale capaciteit te reizen. Ze besluiten om meer te rekenen wanneer voertuigen minder passagiers hebben en stimuleren volledige voertuigen door lagere prijzen aan te bieden:

  • Auto's en taxi's zonder passagiers betalen een extra $ 0,50.
  • Auto's en taxi's met twee passagiers krijgen een korting van $ 0,50.
  • Auto's en taxi's met drie of meer passagiers krijgen een korting van $ 1,00.
  • Bussen die minder dan 50% vol zijn, betalen een extra $ 2,00.
  • Bussen die meer dan 90% vol zijn, krijgen een korting van $ 1,00.

U kunt deze regels implementeren met behulp van een eigenschapspatroon in dezelfde switchexpressie. Een eigenschapspatroon vergelijkt een eigenschapswaarde met een constante waarde. Het property-patroon onderzoekt eigenschappen van het object zodra het type is bepaald. Car {Passengers: 0} is zelf een recursief patroon: het buitenste eigenschapspatroon bevat Car een innerlijk constant patroon waarmee de Passengers-waarde wordt getest. Het ene geval voor een Car breidt zich uit tot vier verschillende gevallen:

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,

    // ...
};

In de eerste drie gevallen wordt het type getest als een Car, en controleert u vervolgens de waarde van de Passengers eigenschap. Als beide overeenkomen, wordt de expressie geëvalueerd en geretourneerd.

U kunt ook de gevallen voor taxi's op een vergelijkbare manier uitbreiden:

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,

    // ...
};

Implementeer vervolgens de bezettingsregels door de gevallen voor bussen uit te breiden, zoals wordt weergegeven in het volgende voorbeeld:

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,

    // ...
};

De tolinstantie houdt zich niet bezig met het aantal passagiers in de bestelwagens. In plaats daarvan passen ze het tolbedrag als volgt aan op basis van de gewichtsklasse van de vrachtwagens:

  • Vrachtwagens van meer dan 5000 lbs worden extra $5,00 in rekening gebracht.
  • Lichte vrachtwagens onder de 3000 pond krijgen een korting van $ 2,00.

U kunt deze regel implementeren met de volgende code:

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

De voorgaande code toont de when clausule van een schakelarm. Gebruik de when clausule om andere voorwaarden dan gelijkheid voor een eigenschap te testen. Wanneer u klaar bent, hebt u een methode die er ongeveer als volgt uitziet:

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

Zoals eerder vermeld, zijn deze switch-armen recursieve patronen, waarbij een constant patroon binnen een eigenschapspatroon wordt genest.

U kunt deze code minder herhalend maken met behulp van geneste switches. De Car en Taxi beide hebben vier verschillende armen in de voorgaande voorbeelden. In beide gevallen kunt u een declaratiepatroon maken dat leidt tot een constant patroon. Deze techniek wordt weergegeven in de volgende code:

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

In het voorgaande voorbeeld betekent het nesten van een switchexpressie in een andere switch-arm dat u de Car en Taxi-armen met onderliggende armen die de waarde van de eigenschap testen niet herhaalt. Deze techniek wordt niet gebruikt voor de Bus en DeliveryTruck armen, omdat deze armen bereiken voor de eigenschap testen, geen discrete waarden.

Piekprijzen toevoegen

Voor de laatste functie wil de tolinstantie tijdgevoelige piekprijzen toevoegen. Tijdens de ochtend- en avonddrukuren worden de tolgelden verdubbeld. Deze regel is alleen van invloed op verkeer in één richting: binnenkomend naar de stad in de ochtend en uitgaand in het spitsuur van de avond. Tijdens andere tijden tijdens de werkdag nemen tolgelden met 50% toe. Laat in de nacht en vroeg in de ochtend worden de tolgelden met 25% verlaagd. Tijdens het weekend is het de normale snelheid, ongeacht de tijd. U kunt een reeks else- en if-instructies gebruiken om deze regel uit te drukken met behulp van de volgende code:

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

De voorgaande code werkt correct, maar is niet leesbaar. Je moet alle invoercases en de geneste if instructies doorlopen om over de code te redeneren. In plaats daarvan gebruikt u patroonkoppeling voor deze functie, maar integreert u deze met andere technieken. U kunt één patroonvergelijkingsuitdrukking maken die rekening houdt met alle combinaties van richting, dag van de week en tijd. Het resultaat zou een gecompliceerde expressie zijn. Het zou moeilijk te lezen en moeilijk te begrijpen zijn. Dat maakt het moeilijk om de juistheid te garanderen. Combineer in plaats daarvan deze methoden om een tuple met waarden te bouwen die al deze statussen beknopt beschrijven. Gebruik vervolgens patroonkoppeling om een vermenigvuldiger voor de tol te berekenen. De tuple bevat drie discrete voorwaarden:

  • De dag is een weekdag of een weekend.
  • De periode waarin de tol wordt verzameld.
  • De richting is de stad in of de stad uit.

In de volgende tabel ziet u de combinaties van invoerwaarden en de vermenigvuldiger met piekprijzen:

Dag Tijd Direction Premium
Weekdag ochtendspits inbound x 2.00
Weekdag ochtendspits outbound x 1.00
Weekdag daglicht inbound x 1,50
Weekdag daglicht outbound x 1,50
Weekdag avondspits inbound x 1.00
Weekdag avondspits outbound x 2.00
Weekdag overnachten inbound x 0,75
Weekdag overnachten outbound x 0,75
Weekeinde ochtendspits inbound x 1.00
Weekeinde ochtendspits outbound x 1.00
Weekeinde daglicht inbound x 1.00
Weekeinde daglicht outbound x 1.00
Weekeinde avondspits inbound x 1.00
Weekeinde avondspits outbound x 1.00
Weekeinde overnachten inbound x 1.00
Weekeinde overnachten outbound x 1.00

Er zijn 16 verschillende combinaties van de drie variabelen. Door een aantal voorwaarden te combineren, vereenvoudigt u de uiteindelijke switchexpressie.

Het systeem dat de tolheffingen verzamelt, gebruikt een DateTime structuur voor het tijdstip waarop de tol werd verzameld. Bouw lidmethoden waarmee de variabelen uit de voorgaande tabel worden gemaakt. De volgende functie maakt gebruik van een switch-expressie voor patroonmatching om aan te geven of een DateTime een weekend of een weekdag vertegenwoordigt.

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

Die methode is juist, maar het is herhalend. U kunt dit vereenvoudigen, zoals wordt weergegeven in de volgende code:

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

Voeg vervolgens een vergelijkbare functie toe om de tijd in de blokken te categoriseren:

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

U voegt een privé enum toe om elk tijdsbereik te converteren naar een discrete waarde. Vervolgens gebruikt de GetTimeBand methode relationele patronen en logische patronen. Met een relationeel patroon kunt u een numerieke waarde testen met behulp van <, >of <=>=. Logische patronen combineren andere patronen: een or-patroon test of een expressie overeenkomt met een of meer patronen, een and-patroon test of een expressie overeenkomt met twee verschillende patronen en een not-patroon test of een expressie niet overeenkomt met een patroon.

Nadat u deze methoden hebt gemaakt, kunt u een andere switch expressie gebruiken met een tuple-patroon ( een positioneel patroon dat overeenkomt met elk element van een tuple) om de prijspremie te berekenen. U kunt een switch expressie bouwen met alle 16 armen:

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

De voorgaande code werkt, maar kan worden vereenvoudigd. Alle acht combinaties voor het weekend hebben dezelfde tol. U kunt alle acht vervangen door de volgende regel:

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

Zowel inkomend als uitgaand verkeer hebben dezelfde vermenigvuldiger tijdens de weekdag overdag en 's nachts. U kunt deze vier schakelarmen vervangen door de volgende twee regels:

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

De code moet eruitzien als de volgende code na deze twee wijzigingen:

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

Verwijder ten slotte de twee spitstijden waarvoor de normale prijs geldt. Nadat u deze armen hebt verwijderd, vervangt u de false door een weggooiactie (_) in de laatste switch-arm. U krijgt de volgende voltooide methode:

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

In dit voorbeeld ziet u een van de voordelen van patroonkoppeling: de patroontakken worden op volgorde geëvalueerd. Als u deze opnieuw rangschikt zodat een eerdere vertakking een van uw latere gevallen afhandelt, waarschuwt de compiler u voor de onbereikbare code. Deze taalregels maakten het eenvoudiger om de voorgaande vereenvoudigingen uit te voeren met het vertrouwen dat de code niet is gewijzigd.

Patroonkoppeling maakt sommige typen code beter leesbaar en biedt een alternatief voor objectgeoriënteerde technieken wanneer u geen code aan uw klassen kunt toevoegen. De cloud zorgt ervoor dat gegevens en functionaliteit uit elkaar blijven. De vorm van de gegevens en de bewerkingen erop worden niet noodzakelijkerwijs samen beschreven. In deze zelfstudie hebt u bestaande gegevens op geheel verschillende manieren gebruikt dan de oorspronkelijke functie. Met patroonkoppeling hebt u de mogelijkheid om functionaliteit te schrijven die deze typen overbelasten, ook al kunt u ze niet uitbreiden.

Volgende stappen 

U kunt de voltooide code downloaden uit de GitHub-opslagplaats dotnet/samples . Verken zelf patronen en voeg deze techniek toe aan uw reguliere coderingsactiviteiten. Het leren van deze technieken biedt u een andere manier om problemen te benaderen en nieuwe functionaliteit te creëren.

Zie ook