All'interno di switchun'istruzione di corrispondenza del modello che utilizza a caseper un tipo esplicito si chiede se il valore in questione è di quel tipo specifico o di un tipo derivato. È l'esatto equivalente diis
switch (someString) {
case string s:
}
if (someString is string)
Il valore nullnon ha un tipo e quindi non soddisfa nessuna delle condizioni precedenti. Il tipo statico di someStringnon entra in gioco in nessuno dei due esempi.
Il vartipo anche se nella corrispondenza del modello agisce come un carattere jolly e corrisponderà a qualsiasi valore incluso null.
Il defaultcaso qui è codice morto. Il case var ocorrisponderà qualsiasi valore, null o non null. Un caso non predefinito vince sempre su uno predefinito, quindi defaultnon verrà mai colpito. Se guardi l'IL vedrai che non viene nemmeno emesso.
A prima vista può sembrare strano che questo si compili senza alcun preavviso (decisamente mi ha sbalordito). Ma questo corrisponde al comportamento di C # che risale a 1.0. Il compilatore consente defaultcasi anche quando può provare banalmente che non verrà mai colpito. Considera come esempio quanto segue:
bool b = ...;
switch (b) {
case true: ...
case false: ...
default: ...
}
Qui defaultnon verrà mai colpito (nemmeno perbool se ha un valore diverso da 1 o 0). Tuttavia C # lo ha consentito dalla 1.0 senza preavviso. Il pattern matching è in linea con questo comportamento qui.
oèstring(confermata con i generici - cioèFoo(o)doveFoo<T>(T template) => typeof(T).Name) - è un caso molto interessante in cuistring xsi comporta in modo diversovar xanche quandoxviene digitato (dal compilatore) comestring