我试图理解为什么y
在以下示例中的范围内:
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...
}
如果我将int x
更改为object x
,则y
不再在范围内(正如预期的那样)。
当匹配的表达式为y
类型而不是类型为int
时,为什么object
在范围内?奇怪的是,范围根据表达式类型而变化。
y
似乎保留在范围内,并且它们都是值类型。 (当两种类型都是DateTime
时存在同样的问题,但当它们都是string
时都不存在。
(csc版本是2.0.0.61213。)
更新:在这两种情况下看起来y
都在范围内。在object
情况下,编译器错误是"使用未分配的本地变量' y'。"因此,它不会抱怨变量超出范围。
答案 0 :(得分:2)
问题是创建的输出代码,导致这种奇怪的行为,这是我认为的一个错误。我想这最终会得到解决。
问题是:x is int y
在编译时评估true
,导致if
呈现过时,并且在{{1}之前完成了作业}}。 See the compiled code here:
if
int num = 1;
int num2 = num;
bool flag = true;
if (flag)
{
}
Console.WriteLine("This should NOT be in scope:" + num2);
变体的编译中似乎存在错误。它编译成这样的东西(注意我添加的括号):
is object
哪个有效,即使在C#6中也是如此。但是,编译器认为int num = 1;
object arg;
bool flag = (arg = num as object) != null;
Console.WriteLine("This should NOT be in scope:" + arg);
并不总是设置。添加arg
分支修复了此错误:
else
else { y = null; }
答案 1 :(得分:1)
这是我在VS15P4(或P5)中找到的东西,它正在GitHub上被跟踪:
Definite assignment versus pattern-matching when pattern always matches #14651
暂且不谈所有讨论,这是一个范围问题,当模式总是匹配时,就像标题所示。
我认为它在RC之前已经修复,所以我事后没有进行过测试,但似乎问题仍然存在。
让我们看看它是否会在实际版本中修复,明天就是:)