Pattern matching - variable in scope outside if-block

余生长醉 提交于 2019-12-01 09:04:33

问题


I'm trying to understand why y is in scope in the following example:

static void Main(string[] args)
{
    int x = 1;
    if (x is int y) { }

    Console.WriteLine("This should NOT be in scope:" + y); // but it is...
}

If I change int x to object x, then y is no longer in scope (as expected).

Why is y in scope when the expression being matched is of int type and not when the type is object? It's odd that the scoping changes based on the expression type.

y seems to stay in scope when the expression type and the pattern type are the same, and they're both value types. (Same issue exists when both types are DateTime, but doesn't exist when they're both string).

(csc version is 2.0.0.61213.)


Update: It looks like y is in scope in both cases. In the object case, the compiler error is "Use of unassigned local variable 'y'." So it's not complaining about the variable being out of scope.


回答1:


The problem is the output code created, which results in this strange behavior, which is a bug in my opinion. I guess this will be fixed eventually.

The thing is this: x is int y evaluates to true on compile time, resulting in the if rendered obsolete and the assignment done before the if. See the compiled code here:

int num = 1;
int num2 = num;
bool flag = true;
if (flag)
{
}
Console.WriteLine("This should NOT be in scope:" + num2);

There seems a bug in the compilation of the is object variant. It compiles to something like this (note the parenthesis I added):

int num = 1;
object arg;
bool flag = (arg = num as object) != null;

Console.WriteLine("This should NOT be in scope:" + arg);

Which is valid, even in C# 6. However, the compiler thinks arg isn't always set. Adding an else branch fixes this bug:

else { y = null; }

Results in:

int num = 1;
object arg;
bool flag = arg = num as object != null;
if (!flag)
{
    arg = null;
}
Console.WriteLine("This should NOT be in scope:" + arg);



回答2:


That's is something I had found in VS15P4 (or P5) and it was being tracked on GitHub:

Definite assignment versus pattern-matching when pattern always matches #14651

Putting aside all the discussions, it is a scoping issue which occurs when the pattern always matches, as the title suggests.

I thought it was fixed before RC so I haven't actually tested afterwards but it seems the issue still persists.

Let's see if it will be fixed in the actual release, which is tomorrow :)



来源:https://stackoverflow.com/questions/42483485/pattern-matching-variable-in-scope-outside-if-block

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!