Patronen weergeven en segmenteren

Tip

Dit artikel maakt deel uit van de sectie Grondbeginselen voor ontwikkelaars die al ten minste één programmeertaal kennen en C# leren. Begin met het overzicht van patroonkoppeling als patronen nieuw voor u zijn. Zie lijstpatronen in de taalreferentie voor de volledige regels voor ondersteunde typen en talen.

De vorm van een reeks is de set waarneembare eigenschappen die een patroon vereist. Deze eigenschappen kunnen bestaan uit het aantal elementen, vereisten die zijn geschreven voor elk element of voor een reeks elementen als geheel en markeringswaarden bij specifieke indexen. Een shape kan bijvoorbeeld precies twee elementen vereisen met "Name" op index 0, of een eerste markering, een laatste markering en een niet-lege reeks daartussen.

Een lijstpatroon beschrijft een vorm door een vereiste voor het aantal elementen te combineren met geneste patronen op geordende posities. Hiermee worden alleen de vereisten getest die in het patroon zijn geschreven: een subpatroon van een element test het bijbehorende element, terwijl een segmentpatroon een reeks anders niet-overeenkomende elementen kan toestaan of testen. U kunt deze onderdelen gebruiken om een exacte telling en markeringswaarden te vinden, waarden vast te leggen op vaste posities, een niet-overeenkomend midden toe te staan of een genest patroon op dat midden toe te passen.

Kies een lijstpatroon wanneer het compile-time-type van de invoer een eigenschap Length of Count en geïndexeerde elementtoegang heeft, waarbij een element op basis van de positie wordt opgehaald, zoals in input[index]. Matrices, List<T>tekenreeksen en spanten zijn veelvoorkomende voorbeelden. De compiler bepaalt de geschiktheid op basis van het gedeclareerde compile-time-type van de variabele, omdat deze vereiste leden moeten worden bepaald voordat het programma wordt uitgevoerd. De IEnumerable<T> interface zelf biedt opsomming in plaats van die leden, zelfs wanneer het runtimeobject een indexeerbare verzameling is.

Lijstpatronen gebruiken een lengte of aantal en geïndexeerde elementtoegang in plaats van opsomming. Voor veelvoorkomende ingebouwde typen hoeft patroonovereenkomst alleen de posities te controleren die door het patroon worden benoemd, in plaats van over elk element te itereren. De kosten van deze bewerkingen zijn afhankelijk van het invoertype. Het herhalen van een lange verzameling kan tijd duren, dus gebruik een lus of LINQ wanneer voor de beslissing een willekeurig aantal elementen moet worden onderzocht in plaats van specifieke posities.

Een exacte vorm zoeken

Met de volgende methode wordt een kop met twee kolommen herkend:

static bool IsHeader(string[] columns) =>
    columns is ["Name", "Score"];

De columns expressie is de patrooninvoer. ["Name", "Score"] bevat twee constante patronen. Een exact lijstpatroon laat een segmentpatroon weg, vereist exact twee elementen en past elk geneste patroon toe op het element in dezelfde index. Dit patroon beschrijft een shape met een exacte telling en twee markeringswaarden: "Name" bij index 0 en "Score" bij index 1. Geneste elementpatronen zijn optioneel: het lege lijstpatroon [] beschrijft en komt overeen met een reeks zonder elementen.

Kies een lijstpatroon wanneer de vorm een bepaald aantal elementen omvat met vereisten voor specifieke posities. Als alleen het aantal elementen van belang is, geeft een Length of Count eigenschapspatroon, zoals items is { Count: 0 }, die intentie meer rechtstreeks aan.

Een verwijdering gebruiken om overeen te komen met een elementwaarde

Met de volgende methode worden de winnaar en de nummer drie gelezen uit een finishvolgorde van drie namen:

static string GetAnnouncements(List<string> finishingOrder) =>
    finishingOrder switch
    {
        [var winner, _, var thirdPlace] =>
            $"Winner: {winner}; third place: {thirdPlace}",
        _ => "A complete three-runner result isn't available"
    };

De var winner en var thirdPlace patronen declareren elk een variabele. Wanneer het lijstpatroon overeenkomt, wijst C# de overeenkomende elementwaarde op die positie toe aan de bijbehorende variabele, zodat het resultaat kan worden gebruikt winner en thirdPlace. Het verwijderingspatroon _ accepteert het tweede element en negeert de waarde ervan. Deze shape vereist precies drie elementen en geeft de eerste en derde positie specifieke betekenis, maar vereist geen specifieke waarden op een willekeurige positie.

Kies dit formulier wanneer vaste posities een stabiele betekenis hebben. Gebruik een lus of LINQ wanneer u een willekeurig aantal elementen moet inspecteren, een reeks moet transformeren, overal moet zoeken of aggregatie wilt uitvoeren.

Resterende elementen met een segmentpatroon toestaan

In dit vereenvoudigde voorbeeld kan een opdrachtregel beginnen met --verbose, andere argumenten bevatten, en wordt ervan uitgegaan dat die eindigt op de naam van het invoerbestand. De volgende methode herkent shapes met een bestandsnaam op de laatste positie en legt die waarde vast:

static string GetInputFile(string[] arguments) =>
    arguments switch
    {
        ["--verbose", .., var fileName] => $"Verbose processing: {fileName}",
        [.., var fileName] => $"Processing: {fileName}",
        [] => "No input file was provided"
    };

Het segmentpatroon.. staat nul of meer resterende elementen toe tussen de patronen van het eerste en laatste element. Een lijstpatroon kan maximaal één segmentpatroon bevatten. De eerste schakelarm beschrijft een shape met ten minste twee elementen: de markering "--verbose" bij index 0, een bestandsnaam op de laatste positie en een willekeurig aantal niet-overeenkomende argumenten ertussen. In het zelfstandige segment worden deze middelste argumenten niet getest. De tweede arm accepteert een lege vorm en legt het laatste element vast, terwijl het lege patroon een reeks zonder elementen afhandelt.

Een segment kan worden weergegeven aan het begin, midden of einde van een lijstpatroon. Gebruik deze functie wanneer een reeks variabele lengte deel uitmaakt van de shape, maar alleen de omringende posities elementtests nodig hebben. Gebruik gewone iteratie wanneer elk element moet worden verwerkt.

Een patroon toepassen op een segment

U kunt een ander patroon toepassen op het gedeelte dat overeenkomt met ... Met de volgende methode wordt getest of een matrix begint met "BEGIN", eindigt met "END"en ten minste één element bevat:

static bool HasContent(string[] entries) =>
    entries is ["BEGIN", .. { Length: > 0 }, "END"];

Het buitenste patroon vereist eerst de markering "BEGIN" bij index 0 en "END" bij de laatste index. Het eigenschapspatroon { Length: > 0 } voegt vervolgens een vereiste toe voor de reeks die overeenkomt met het segment: het moet ten minste één element bevatten. Samen beschrijven deze vereisten de volledige vorm. Met het patroon worden de waarden van de elementen in het segment niet getest.

Gebruik een segmentsubpatroon alleen wanneer het middelste gedeelte zelf een test of opname nodig heeft. Als alleen randelementen belangrijk zijn, is een gewone .. eenvoudiger.

Zie ook