Modelli di elenco e sezioni

Tip

Questo articolo fa parte della sezione Nozioni fondamentali per gli sviluppatori che già conoscono almeno un linguaggio di programmazione e stanno imparando C#. Iniziate con la panoramica della corrispondenza dei modelli se non conoscete ancora i modelli. Per informazioni complete sulle regole di tipo e lingua supportate, vedere modelli di elenco nelle informazioni di riferimento sul linguaggio.

La forma di una sequenza è l'insieme delle proprietà osservabili che un modello richiede. Queste proprietà possono includere il numero di elementi, i requisiti scritti per ogni elemento o per una sequenza di elementi nel suo complesso e i valori dell'indicatore in corrispondenza di indici specifici. Ad esempio, una struttura potrebbe richiedere esattamente due elementi con "Name" all’indice 0, oppure potrebbe richiedere un primo marcatore, un ultimo marcatore e una sequenza non vuota tra di essi.

Un modello di elenco descrive una forma combinando un requisito di conteggio degli elementi con modelli annidati in posizioni ordinate. Verifica solo i requisiti definiti nel pattern: un sottopattern di elemento verifica l'elemento corrispondente, mentre uno slice pattern può consentire o verificare una sequenza di elementi che altrimenti non troverebbero corrispondenza. È possibile usare queste parti per far corrispondere un conteggio esatto e i valori dei marcatori, acquisire i valori in posizioni fisse, consentire una parte centrale non corrispondente o applicare uno schema annidato a tale parte centrale.

Scegliere un pattern di elenco quando il tipo dell'input in fase di compilazione fornisce una proprietà Length o Count e l'accesso indicizzato agli elementi, che consente di recuperare un elemento in base alla sua posizione, come in input[index]. Le matrici, List<T>le stringhe e gli intervalli sono esempi comuni. Il compilatore determina l'idoneità dal tipo dichiarato e in fase di compilazione della variabile perché deve risolvere questi membri necessari prima dell'esecuzione del programma. L'interfaccia IEnumerable<T> di per sé fornisce l'enumerazione anziché tali membri, anche quando l'oggetto in fase di esecuzione è una raccolta indicizzabile.

I pattern di lista usano una lunghezza o un conteggio e l'accesso indicizzato agli elementi invece dell'enumerazione. Per i tipi predefiniti più comuni, il confronto può controllare solo le posizioni specificate dal pattern anziché iterare su ogni elemento. Il costo di tali operazioni dipende dal tipo di input. L'iterazione di una raccolta lunga può richiedere tempo, quindi usare un ciclo o LINQ quando la decisione richiede l'esame di un numero arbitrario di elementi anziché posizioni specifiche.

Abbina una forma esatta

Il metodo seguente riconosce un'intestazione a due colonne:

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

L'espressione columns è l'input del modello. ["Name", "Score"] contiene due modelli costanti. Un criterio di elenco esatto omette un criterio di sezione, richiede esattamente due elementi e applica ogni modello annidato all'elemento con lo stesso indice. Questo modello descrive una forma con un conteggio esatto e due valori marcatori: "Name" in corrispondenza dell'indice 0 e "Score" in corrispondenza dell'indice 1. I modelli di elementi annidati sono facoltativi: il modello di elenco vuoto [] descrive e corrisponde a una sequenza senza elementi.

Scegli un pattern di elenco quando la struttura combina un numero di elementi con requisiti in posizioni specifiche. Se conta solo il numero di elementi, un property pattern Length o Count, ad esempio items is { Count: 0 }, esprime tale intento in modo più diretto.

Usare un'eliminazione per trovare la corrispondenza con qualsiasi valore dell'elemento

Il metodo seguente legge il vincitore e il classificato al terzo posto da un ordine di arrivo composto da tre nomi:

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

I modelli var winner e var thirdPlace dichiarano ciascuno una variabile. Quando il criterio di elenco corrisponde, C# assegna il valore dell'elemento corrispondente in tale posizione alla variabile corrispondente, in modo che il risultato possa usare winner e thirdPlace. Il criterio _ di eliminazione accetta il secondo elemento e ne rimuove il valore. Questa forma richiede esattamente tre elementi e dà il significato specifico alla prima e alla terza posizione, ma non richiede valori specifici in nessuna posizione.

Scegliere questo modulo quando le posizioni fisse hanno un significato stabile. Usare un ciclo o LINQ quando è necessario esaminare un numero arbitrario di elementi, trasformare una sequenza, eseguire una ricerca in tutto il ciclo o eseguire l'aggregazione.

Consenti elementi rimanenti con un criterio di sezione

In questo esempio semplificato, una riga di comando può iniziare con --verbose e contenere altri argomenti e si presuppone che termini con il nome del file di input. Il metodo seguente riconosce le forme con un nome di file nell'ultima posizione e acquisisce tale valore:

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

Il modello slice.. consente zero o più elementi restanti tra i pattern del primo e dell’ultimo elemento. Un pattern di elenco può contenere al massimo un pattern di slice. Il primo ramo dello switch descrive una struttura con almeno due elementi: il marcatore "--verbose" all'indice 0, un nome di file nell'ultima posizione e un numero qualsiasi di argomenti non associati tra questi. Lo slice standalone non verifica quegli argomenti intermedi. Il secondo braccio accetta qualsiasi forma non vuota e acquisisce l'ultimo elemento, mentre il motivo vuoto gestisce una sequenza senza elementi.

Un segmento può comparire all'inizio, nel mezzo o alla fine di un modello di elenco. Usarlo quando una sequenza di lunghezza variabile fa parte della forma, ma solo le posizioni circostanti necessitano di test degli elementi. Usare l'iterazione normale quando ogni elemento richiede l'elaborazione.

Applicare un modello a una sezione

È possibile applicare un altro modello alla parte corrispondente a ... Il metodo seguente verifica se una matrice inizia con , termina con "BEGIN""END"e include almeno un elemento tra di essi:

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

Il modello esterno richiede prima di tutto l'indicatore "BEGIN" in corrispondenza dell'indice 0 e "END" dell'ultimo indice. Il modello { Length: > 0 } di proprietà aggiunge quindi un requisito per la sequenza corrispondente alla sezione: deve contenere almeno un elemento. Insieme, questi requisiti descrivono la forma completa. Il pattern non verifica i valori degli elementi all'interno della slice.

Usare un sottopattern di slice solo quando la parte centrale richiede un test o una cattura. Se contano solo gli elementi di delimitazione, il solo .. è più semplice.

Vedere anche