Inside a pattern matching switch
statement using a case
for an explicit type is asking if the value in question is of that specific type, or a derived type. It's the exact equivalent of is
switch (someString) {
case string s:
}
if (someString is string)
The value null
does not have a type and hence does not satisfy either of the above conditions. The static type of someString
doesn't come into play in either example.
The var
type though in pattern matching acts as a wild card and will match any value including null
.
The default
case here is dead code. The case var o
will match any value, null or non-null. A non-default case always wins over a default one hence default
will never be hit. If you look at the IL you'll see it's not even emitted.
At a glance it may seem odd that this compiles without any warning (definitely threw me off). But this is matching with C# behavior that goes back to 1.0. The compiler allows default
cases even when it can trivially prove that it will never be hit. Consider as an example the following:
bool b = ...;
switch (b) {
case true: ...
case false: ...
default: ...
}
Here default
will never be hit (even for bool
that have a value that isn't 1 or 0). Yet C# has allowed this since 1.0 without warning. Pattern matching is just falling in line with this behavior here.