模式匹配 - if-block之外的范围变量

时间:2017-02-27 10:34:50

标签: c# pattern-matching c#-7.0

我试图理解为什么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'。"因此,它不会抱怨变量超出范围。

2 个答案:

答案 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

Results in

else { y = null; }

答案 1 :(得分:1)

这是我在VS15P4(或P5)中找到的东西,它正在GitHub上被跟踪:

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

暂且不谈所有讨论,这是一个范围问题,当模式总是匹配时,就像标题所示。

我认为它在RC之前已经修复,所以我事后没有进行过测试,但似乎问题仍然存在。

让我们看看它是否会在实际版本中修复,明天就是:)