Wewnątrz switch
instrukcji dopasowywania wzorców używająca a case
dla 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ść null
nie 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 .
var
Typ choć w strukturze dopasowywania działa jako dzikie karty i będzie pasował do żadnej wartości łącznie null
.
default
Sprawa tutaj jest martwy kod. case var o
Dopasuje jakąkolwiek wartość, null lub niezerowe. Przypadki inne niż domyślne zawsze wygrywają z przypadkami domyślnymi, więc default
nigdy 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 default
przypadki, 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 default
nigdy nie zostanie trafiony (nawet jeśli bool
ma 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.
o
jeststring
(potwierdzone z rodzajowych - czyliFoo(o)
gdzieFoo<T>(T template) => typeof(T).Name
) - jest to bardzo ciekawy przypadek, w którymstring x
zachowuje się inaczej niżvar x
nawet gdyx
jest wpisane (przez kompilator) jakostring