For some reason, M1()
causes a compiler error, while M2()
, which does the same thing, causes no error. Any idea why?
Using false ==>
The issue here is with the way the compiler handles "definitely assigned when true". !
inverts that; == false
doesn't. So for the code:
if (!(obj is int i))
return;
System.Console.WriteLine(i);
The compiler can infer that if obj is int i
is false, the !
inverts that, thus return
will occur if it's not an int
. Therefore i
can be allowed to "leak" into subsequent code safely.
However, the same rules do not apply to == false
. Whilst semantically identical to a human reader of the code, the compiler treats !
and == false
as very different things. So for:
if (false == (obj is int i))
the compiler baulks and takes the view it cannot know the assignment state of i
, thus the error.
For a discussion on this, please see Incorrect "Use of unassigned local variable" for (x is T y) == false.
The moral of the story: avoid comparing to false
and use !
when using C# patterns.
EDIT
It should be noted that == false
is not a special case here. Any use of ==
removes the ability of the compiler to determine "definitely assigned when true". For example, the following code compiles:
object x = 1;
if (!(x is bool y))
return 0;
var z = y;
But add a == true
and it no longer does:
object x = 1;
if (!(x is bool y == true))
return 0;
var z = y; // error: use of an unassigned variable
EDIT2
Incidently, for anyone who uses if (expression == false)
because they find if (!expression)
difficult to read, you may be interested to know that the syntax, if !(expression) is being considered for C# 8.