Внутри оператора сопоставления с образцом switchс использованием a caseдля явного типа задается вопрос, относится ли значение к этому конкретному типу или к производному типу. Это точный эквивалентis
switch (someString) {
case string s:
}
if (someString is string)
Значение nullне имеет типа и, следовательно, не удовлетворяет ни одному из вышеуказанных условий. Статический типsomeString не используется ни в одном из примеров.
В varТипа , хотя в шаблоне соответствие действует как джокер и будет соответствовать любому значению , включая null.
defaultДело здесь мертв код. Вcase var oБудет соответствовать любое значение, нулевое или ненулевое значение. Случай не по умолчанию всегда побеждает случай по умолчанию, поэтому defaultникогда не будет выполнен. Если вы посмотрите на IL, вы увидите, что он даже не испускается.
На первый взгляд может показаться странным, что это компилируется без какого-либо предупреждения (определенно меня сбило с толку). Но это соответствует поведению C #, восходящему к версии 1.0. Компилятор допускает defaultслучаи, даже если он может тривиально доказать, что в него никогда не попадут. Рассмотрим в качестве примера следующее:
bool b = ...;
switch (b) {
case true: ...
case false: ...
default: ...
}
Здесь defaultникогда не будет попадания (даже boolесли оно имеет значение, отличное от 1 или 0). Тем не менее, C # позволяет это без предупреждения с версии 1.0. Сопоставление с образцом здесь просто соответствует этому поведению.
oкотороеstring(подтверждено с помощью дженериков - т.е.Foo(o)гдеFoo<T>(T template) => typeof(T).Name) - это очень интересный случай, когдаstring xведет себя иначе, чемvar xдаже когдаxон набирается (компилятором) какstring