2016-11-18 95 views
6

Roslyn Pattern Matching spec它指出:模式匹配变量范围

的图案可变的范围如下:

如果图案出现在一个if语句的条件下,它的范围 是if语句的条件和受控语句,但不包含其他语句。

但是微软最新的“最新消息” postspresentations都出现了这个例子:

public void PrintStars(object o) 
{ 
    if (o is null) return;  // constant pattern "null" 
    if (!(o is int i)) return; // type pattern "int i" 
    WriteLine(new string('*', i)); 
} 

足见模式匹配外的模式匹配的,如果水平范围使用i变量。

这是一个疏忽,还是已经从规范改变范围?

+0

这将是if语句的_controlled语句_ – juharr

+0

@juharr,那么受控语句只会返回吗? –

+0

是的,我错过了。实际上,我认为这可能是指更高范围的“i”,但很难说,因为它是测试版功能的代码片段。我想你可以预览并测试它。 – juharr

回答

3

我张贴a similar question的罗斯林的问题,并通过DavidArno给出了答案:

它的长,但你可以阅读的为什么语言 设计团队选择了“加强”的复杂细节这种语言在#12939

TL; DR你并不孤单,认为改变不直观, 矛盾的范围以前的工作方式。团队可悲的 不在乎,但变化是留在这里。

似乎作出决定,这个范围界定将适用,因此该规范已经过时了,这作用域是可悲的是在这里留下来:

方案3:表达式变量由作用域块,,的foreach和 using语句,以及所有嵌入式声明:

什么是这里的嵌入语句的意思,是一个被用作另一语句 嵌套声明 - 除了块内。因此 if语句的分支,while,foreach等 都将被视为嵌入。

其后果是,变量总是会逃避 的条件,如果,但从来没有它的分支。就好像你在所有“你应该”的地方放置了所有的 。

结论

虽然有点微妙,我们将通过选项3.击中了良好的平衡 :

它使关键场景,包括了瓦尔非试方法,如 以及模式并在保镖if语句中列出变数。它不会导致异常和反直觉的多层次“溢出”。它意味着你将会得到比目前的限制性制度更多的变量。这似乎并不危险,因为明确的 赋值分析将阻止未初始化的使用。但是, 会阻止重复使用变量名称,并导致在完成列表中显示更多名称 。这似乎是一个合理的折衷。

2

从同一个文档:

由图案引入的变量 - 类似于前面所以其实这个代码描述

了出来变量:

if (!(o is int i)) return; // type pattern "int i" 

更或更少等于:

int i; 
if (!(SomeParsingOn(o, out i))) return; // type pattern "int i" 

这意味着iif的声明级别相同,这意味着它不仅适用于if的范围,还适用于以下声明。这是真实的,可当你复制if作用似乎是:

if (!(o is int i)) return; // type pattern "int i" 
if (!(o is int i)) return; // type pattern "int i" 

给出错误CS0128:命名为“我”在此范围已经定义的局部变量。

+0

感谢您使用预览检查代码!这似乎与规范文档相矛盾,我会在github中搜索任何提及的变化。就我个人而言,我不喜欢这个范围,因为它与大多数定义变量的语法(catch和using)不匹配。 –

+1

嗯,是的,你是对的。这很尴尬。我希望他们能解决它。也许这只是一个错误,或许正在进行中。 –