Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Tip
Questo articolo fa parte della sezione Nozioni fondamentali per gli sviluppatori che già conoscono almeno un linguaggio di programmazione e stanno imparando C#. Iniziare con la panoramica dei criteri di ricerca se in precedenza non sono stati usati modelli C#. Per le regole complete del linguaggio, vedere le informazioni di riferimento sui modelli.
Un modello si applica a un'espressione di input. C# valuta l'espressione, quindi esegue il test del modello o acquisisce il valore risultante. I pattern declaration, constant e var rispondono a tre domande pratiche:
- Modello di dichiarazione: L'espressione ha prodotto un valore non Null di un tipo di runtime compatibile? In tal caso, dichiarare una variabile per tale valore.
- Modello costante: L'espressione ha prodotto un valore costante specifico?
-
varpattern: quale valore ha prodotto l'espressione? Acquisiscilo senza prima verificarne il tipo o il valore.
Testare e acquisire un tipo con un modello di dichiarazione
Un modello di dichiarazione è costituito da un tipo e una designazione. Il tipo specifica il tipo di runtime da testare. La designazione dichiara la variabile che riceve il valore corrispondente.
Nell'esempio seguente viene ricevuto un oggetto object, in modo che l'espressione possa produrre molti tipi diversi. Il modello di dichiarazione consente al ramo corrispondente di usare una quantità decimale senza un test e un cast di tipi separati:
static void PrintPrice(object value)
{
if (value is decimal amount)
{
Console.WriteLine($"Price: {amount:C}");
}
}
In value is decimal amount:
-
valueè l'espressione di ingresso. C# lo valuta per primo. -
decimalè il tipo testato. Il criterio corrisponde quando il valore valutato è diverso da Null e il relativo tipo di runtime è compatibile condecimal. -
amountindica la designazione. Quando il criterio corrisponde, dichiaraamounte assegna il valore decimale.
Il compilatore tiene traccia del fatto che una variabile locale riceva un valore prima della lettura del codice. Questo rilevamento è denominato assegnazione definita. All'interno del if blocco, il compilatore sa che amount è stato assegnato perché il blocco viene eseguito solo quando il criterio corrisponde. Il compilatore genera un errore se il codice tenta di accedere amount all'esterno del if blocco. Se value non è un decimal valore, la variabile amount non viene assegnata a un valore.
Scegliere un modello di dichiarazione quando il ramo corrispondente deve usare il risultato come tipo testato. Combina la dichiarazione di test, conversione e variabile, che evita di ripetere l'espressione o di scrivere un cast separato.
È anche possibile usare modelli di dichiarazione quando un'espressione può produrre diversi tipi utili:
static string FormatSensorValue(object reading) =>
reading switch
{
int count => $"Count: {count}",
double temperature => $"Temperature: {temperature:F1}°C",
string message => $"Message: {message}",
_ => "Unsupported reading"
};
Ogni ramo dichiara una variabile del tipo corrispondente perché il risultato richiede la logica di formattazione di quel tipo. Un pattern di dichiarazione trova corrispondenza solo quando il valore valutato non è null e ha già un tipo in fase di esecuzione compatibile con il tipo verificato tramite le conversioni consentite per i pattern.
null non ha un tipo in fase di esecuzione corrispondente al pattern. Il modello non esegue anche operatori di conversione definiti dall'utente: si tratta di un test di tipo e di acquisizione, non di una richiesta per convertire il valore in un altro tipo. Per le regole di compatibilità complete, vedere Modelli di dichiarazione e tipi.
Trova la corrispondenza di un valore specifico con un modello costante
Un modello costante verifica se un'espressione produce una determinata costante, come un numero, una stringa, un valore booleano, un membro di enumerazione, un valore dichiarato const o null.
I criteri costanti si adattano a un'espressione switch quando diversi valori noti producono un risultato diverso:
static string GetCommandMessage(Command command) =>
command switch
{
Command.Start => "Starting",
Command.Stop => "Stopping",
Command.Pause => "Pausing",
_ => "Unknown command"
};
Command è un'enumerazione, un tipo che definisce un set di costanti denominate.
Command.Start, Command.Stope Command.Pause sono i relativi membri di enumerazione, quindi ogni arm switch usa un modello costante per testare un valore di comando denominato.
Scegliere questo modulo quando il comando può avere diversi significati discreti. I rami dello switch associano i valori ai rispettivi risultati. Per un semplice confronto di uguaglianza, un'istruzione if come if (command == Command.Start) è in genere più facile da leggere.
La corrispondenza dei modelli con costanti usa le regole di uguaglianza integrate del linguaggio anziché un operatore == definito dall'utente. Per informazioni dettagliate sull'uguaglianza e sulle regole di conversione, vedere il riferimento al modello costante.
Il null modello costante è utile per un controllo Null affidabile:
static bool HasText(string? text) => text is not null;
Scegliere is null o is not null quando si sta controllando lo stato Null. Questi criteri non invocano un operatore di uguaglianza definito dall'utente, anche quando il tipo dell'espressione sovraccarica ==.
Acquisisci un risultato per un guard con pattern var
Un var modello corrisponde a qualsiasi risultato, compreso null, e dichiara una variabile il cui tipo è il tipo dell'espressione di input in fase di compilazione. Può acquisire un valore calcolato mentre un altro criterio corrisponde già a un oggetto:
static string GetDeliveryMessage(object delivery) =>
delivery switch
{
ExpressDelivery express
when EstimateDays(express) is var days && days <= 2
=> $"Arrives in {days} day{(days == 1 ? "" : "s")}",
ExpressDelivery => "Express delivery for your location takes more than two days",
_ => "Standard delivery"
};
static int EstimateDays(ExpressDelivery delivery) =>
delivery.MilesAway <= 500 ? 1 :
delivery.MilesAway <= 1_000 ? 2 : 3;
record ExpressDelivery(int MilesAway);
Il modello ExpressDelivery express di dichiarazione acquisisce prima l'oggetto recapito come express. La chiamata di metodo EstimateDays(express) è l'espressione di input per il modello var. C# valuta la chiamata al metodo e var days acquisisce la stima risultante come days senza testarne il tipo o il valore. La stima può essere di uno o due giorni quando la guardia riesce. Il risultato arm richiede il valore acquisito per riportare il numero effettivo di giorni.
Non è possibile dichiarare una variabile locale comune tra un modello switch-arm e la relativa when protezione. La chiamata EstimateDays(express) di nuovo nel risultato ripete il calcolo. Scegliere questo var modello quando il codice è già corrispondente e sia la protezione che il risultato necessitano di un valore intermedio calcolato.
Se non è necessario il valore acquisito, usare il modello _di eliminazione anziché dichiarare una variabile.