Усередині switchоператора збігу шаблонів, що використовує caseдля явного типу, запитується, чи відповідає значення саме тому типу або похідному типу. Це точний еквівалентis
switch (someString) {
case string s:
}
if (someString is string)
Значення nullне має типу і, отже, не задовольняє жодній із зазначених вище умов. Статичний тип someStringне вступає в дію в жодному з прикладів.
varТипу , хоча в шаблоні відповідність діє як джокер і буде відповідати будь-якому значенню , включаючи null.
defaultСправа тут мертвий код. Значення case var oбуде відповідати будь-якому значенню, нульовому чи ненульовому. Справа, що не відповідає замовчуванню, завжди виграє над типовою, отже default, ніколи не буде вражена. Якщо ви подивитесь на ІЛ, то побачите, що він навіть не виділяється.
На перший погляд може здатися дивним, що це компілюється без будь-якого попередження (безумовно, мене відкинуло). Але це відповідає поведінці 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