C# 7 Compiler Error - Pattern Matching

后端 未结 2 515
无人共我
无人共我 2020-12-30 21:08

For some reason, M1() causes a compiler error, while M2(), which does the same thing, causes no error. Any idea why?

Using false ==

2条回答
  •  生来不讨喜
    2020-12-30 21:56

    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.

提交回复
热议问题