Wewnątrz switchinstrukcji dopasowywania wzorców używająca a casedla typu jawnego jest pytaniem, czy dana wartość jest tego konkretnego typu, czy też typu pochodnego. To dokładny odpowiednikis
switch (someString) {
case string s:
}
if (someString is string)
Wartość nullnie ma typu i dlatego nie spełnia żadnego z powyższych warunków. W someStringżadnym z przykładów nie ma znaczenia typ statyczny .
varTyp choć w strukturze dopasowywania działa jako dzikie karty i będzie pasował do żadnej wartości łącznie null.
defaultSprawa tutaj jest martwy kod. case var oDopasuje jakąkolwiek wartość, null lub niezerowe. Przypadki inne niż domyślne zawsze wygrywają z przypadkami domyślnymi, więc defaultnigdy nie zostaną trafione. Jeśli spojrzysz na IL, zobaczysz, że nie jest on nawet emitowany.
Na pierwszy rzut oka może się wydawać dziwne, że kompiluje się to bez żadnego ostrzeżenia (zdecydowanie mnie wyrzuciło). Ale to jest zgodne z zachowaniem C #, które sięga wstecz do 1.0. Kompilator dopuszcza defaultprzypadki, nawet jeśli może w trywialny sposób udowodnić, że nigdy nie zostanie trafiony. Jako przykład rozważ następujące kwestie:
bool b = ...;
switch (b) {
case true: ...
case false: ...
default: ...
}
Tutaj defaultnigdy nie zostanie trafiony (nawet jeśli boolma wartość inną niż 1 lub 0). Jednak C # zezwolił na to od 1.0 bez ostrzeżenia. Dopasowywanie wzorców jest tutaj zgodne z tym zachowaniem.
ojeststring(potwierdzone z rodzajowych - czyliFoo(o)gdzieFoo<T>(T template) => typeof(T).Name) - jest to bardzo ciekawy przypadek, w którymstring xzachowuje się inaczej niżvar xnawet gdyxjest wpisane (przez kompilator) jakostring