由于某些原因, M1()会导致编译器错误,而执行相同操作的 M2()则不会导致错误.知道为什么吗?
For some reason, M1() causes a compiler error, while M2(), which does the same thing, causes no error. Any idea why?
使用 false == 应该与使用not运算符!相同.
Using false == should be the same as using the not operator, !.
使用未分配的局部变量"i"
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 推荐答案此处的问题在于编译器处理"true时绝对分配"的方式.!将其反转; == 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);编译器可以推断出,如果 obj is int i 为false,则!会将其求反,因此如果 return 不是 int .因此,可以允许 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.
但是,相同的规则不适用于 == false .尽管在语义上与人类代码阅读者相同,但编译器将!和 == false 视为完全不同的事物.因此:
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))编译器冒充并认为它不知道 i 的赋值状态,从而导致错误.
the compiler baulks and takes the view it cannot know the assignment state of i, thus the error.
有关此问题的讨论,请参见对于不正确的使用未分配的局部变量"(x是T y)==假 .
For a discussion on this, please see Incorrect "Use of unassigned local variable" for (x is T y) == false.
故事的寓意:使用C#模式时,避免与 false 进行比较,并使用!.
The moral of the story: avoid comparing to false and use ! when using C# patterns.
编辑
应注意, == false 在这里不是特殊情况.任何使用 == 的方法都会使编译器无法确定在true时绝对分配".例如,以下代码编译:
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;但是添加一个 == true ,它将不再起作用:
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 variableEDIT2
顺便说一句,对于使用 if(expression == false)的人,因为他们发现难以理解的 if(!expression),您可能会想知道语法,对于C#8,正在考虑 if!(expression) >.
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.
更多推荐
C#7编译器错误
发布评论