For some reason, M1() causes a compiler error, while M2(), which does the same thing, causes no error. Any idea why?
Using false == should be the same as using the not operator, !.
Use of unassigned local variable 'i'
class Program {
static void Main(string[] args) {
int x = 8;
M1(x);
M2(x);
} // Main()
public static void M1(Object obj) {
if (false == (obj is int i)) // Causes ERROR on WriteLine
return;
System.Console.WriteLine(i); // Use of unassigned local variable 'i'
}
public static void M2(Object obj) {
if (!(obj is int i)) // OKAY
return;
System.Console.WriteLine(i);
}
} // class Program
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With