Wzorce list i wycinków

Wskazówka

Ten artykuł jest częścią sekcji Podstawy dla deweloperów, którzy już znają co najmniej jeden język programowania i uczą się języka C#. Zacznij od omówienia dopasowywania wzorców, jeśli wzorce są dla Ciebie nowe. Aby uzyskać pełne informacje o obsługiwanych typach i regułach języka, zobacz wzorce list w dokumentacji języka.

Kształt sekwencji to zestaw obserwowalnych właściwości, których wymaga wzorzec. Te właściwości mogą obejmować liczbę elementów, wymagania napisane dla każdego elementu lub sekwencję elementów jako całości i wartości znacznika w określonych indeksach. Na przykład dana postać może wymagać dokładnie dwóch elementów, przy czym "Name" znajduje się na indeksie 0, albo pierwszego znacznika, ostatniego znacznika i niepustej sekwencji między nimi.

Wzorzec listowy opisuje kształt przez połączenie wymogu dotyczącego liczby elementów z zagnieżdżonymi wzorcami na uporządkowanych pozycjach. Testuje tylko wymagania zapisane we wzorcu: podwzorzec elementu testuje odpowiadający mu element, podczas gdy wzorzec wycinka może dopuszczać lub sprawdzać ciąg elementów, które w przeciwnym razie pozostałyby niedopasowane. Można użyć tych części, aby dopasować dokładną liczbę elementów i wartości znaczników, przechwytywać wartości na stałych pozycjach, dopuścić niedopasowaną część środkową lub zastosować do niej wzorzec zagnieżdżony.

Wybierz wzorzec listy, jeśli typ wejścia znany w czasie kompilacji udostępnia właściwość Length lub Count oraz indeksowany dostęp do elementów, umożliwiający pobranie elementu na podstawie jego pozycji, jak w input[index]. Tablice, List<T>, ciągi i zakresy są typowymi przykładami. Kompilator określa kwalifikowalność na podstawie zadeklarowanego typu zmiennej znanego w czasie kompilacji, ponieważ musi ustalić te wymagane składowe przed uruchomieniem programu. Sam interfejs IEnumerable<T> zapewnia enumerację zamiast tych składowych, nawet jeśli obiekt w czasie wykonywania jest kolekcją indeksowalną.

Wzorce listy używają długości lub liczby i indeksowanego dostępu do elementu zamiast wyliczania. W przypadku popularnych typów wbudowanych mechanizm dopasowania może sprawdzać tylko pozycje wskazane przez wzorzec, zamiast iterować po każdym elemencie. Koszt tych operacji zależy od typu danych wejściowych. Iterowanie długiej kolekcji może zająć trochę czasu, dlatego użyj pętli lub LINQ, gdy decyzja wymaga zbadania dowolnej liczby elementów, a nie określonych pozycji.

Dopasuj dokładny kształt

Poniższa metoda rozpoznaje nagłówek dwukolumny:

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

Wyrażenie columns to dane wejściowe wzorca. ["Name", "Score"] zawiera dwa wzorce stałe. Ścisły wzorzec listy pomija wzorzec wycinania, wymaga dokładnie dwóch elementów i dopasowuje każdy zagnieżdżony wzorzec do elementu o tym samym indeksie. Ten wzorzec opisuje kształt z dokładną liczbą i dwiema wartościami znacznika: "Name" na indeksie 0 i "Score" na indeksie 1. Zagnieżdżone wzorce elementów są opcjonalne: wzorzec pustej listy [] opisuje sekwencję bez elementów i dopasowuje się do niej.

Wybierz wzorzec listy, gdy wzorzec łączy liczbę elementów z wymaganiami dotyczącymi określonych pozycji. Jeśli znaczenie ma tylko liczba elementów, wzorzec właściwości Count lub items is { Count: 0 }, taki jak Length, wyraża ten zamiar bardziej bezpośrednio.

Użyj odrzucenia, aby dopasować dowolną wartość elementu

Poniższa metoda pobiera zwycięzcę i zawodnika, który zajął trzecie miejsce, z trójelementowej kolejności na mecie:

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

Poszczególne var winner wzorce i var thirdPlace deklarują zmienną. Gdy wzorzec listy zostanie dopasowany, język C# przypisze wartość dopasowanego elementu na danej pozycji do odpowiedniej zmiennej, dzięki czemu w wyniku można użyć winner i thirdPlace. Wzorzec _ odrzucenia akceptuje drugi element i odrzuca jego wartość. Ten kształt wymaga dokładnie trzech elementów i nadaje pierwszej i trzeciej pozycji określone znaczenie, ale nie wymaga określonych wartości na żadnej pozycji.

Wybierz ten formularz, gdy stałe pozycje mają stabilne znaczenie. Użyj pętli lub LINQ, jeśli musisz sprawdzić dowolną liczbę elementów, przekształcić sekwencję, przeszukać ją lub przeprowadzić agregację.

Zezwól na pozostałe elementy pasujące do wzorca wycinka

W tym uproszczonym przykładzie wiersz polecenia może zaczynać się od --verbose i zawierać inne argumenty i zakłada się, że kończy się nazwą pliku wejściowego. Poniższa metoda rozpoznaje kształty o nazwie pliku w ostatniej pozycji i przechwytuje tę wartość:

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

Wzorzec wycinka.. dopuszcza zero lub więcej pozostałych elementów między pierwszym a ostatnim wzorcem elementu. Wzorzec listy może zawierać co najwyżej jeden wzorzec wycinka. Pierwsze ramię przełącznika opisuje strukturę z co najmniej dwoma elementami: znacznikiem "--verbose" na pozycji 0, nazwą pliku na ostatniej pozycji oraz dowolną liczbą niedopasowanych argumentów między nimi. Samodzielny fragment nie testuje tych pośrednich argumentów. Drugie ramię akceptuje dowolny niepusty wzorzec i przechwytuje jego ostatni element, podczas gdy pusty wzorzec dopasowuje sekwencję bez elementów.

Wycinek może pojawić się na początku, środku lub na końcu wzorca listy. Użyj go, gdy sekwencja o zmiennej długości jest częścią kształtu, ale tylko otaczające pozycje wymagają testów elementów. Używaj zwykłej iteracji, gdy każdy element wymaga przetwarzania.

Zastosuj wzorzec do wycinka

Możesz zastosować inny wzorzec do części dopasowanej do ... Poniższa metoda sprawdza, czy tablica rozpoczyna się od "BEGIN", kończy się ciągiem "END"i ma co najmniej jeden element między nimi:

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

Wzorzec zewnętrzny najpierw wymaga, aby znacznik "BEGIN" znajdował się na indeksie 0, a "END" na ostatnim indeksie. Wzorzec właściwości { Length: > 0 } następnie nakłada wymaganie na sekwencję dopasowaną przez wycinek: musi ona zawierać co najmniej jeden element. Razem te wymagania opisują pełny kształt. Wzorzec nie testuje wartości elementów wewnątrz wycinka.

Użyj podwzorca wycinka tylko wtedy, gdy część środkowa wymaga testu lub przechwycenia. Jeśli tylko elementy granic mają znaczenie, zwykły .. jest prostszy.

Zobacz także