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.
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; }
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);
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