在Roslyn Pattern Matching spec中声明:
模式变量的范围如下:
如果模式出现在if语句的条件下,则其范围 是if语句的条件和受控语句,但不是 其他条款。
然而,最新的微软“有什么新内容”posts和presentations显示了这个例子:
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
变量在模式匹配的if级别范围之外使用。
这是疏忽,还是从规范中改变了范围?
答案 0 :(得分:4)
从相同的文档:
模式引入的变量 - 类似于前面描述的输出变量
实际上这段代码:
var Graph = React.createClass({
render: function() {
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow"],
datasets: [{
label: '# of Likes',
data: [12, 19, 3],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)'
]
}]
}
});
}
})
或多或少等于:
if (!(o is int i)) return; // type pattern "int i"
这意味着int i;
if (!(SomeParsingOn(o, out i))) return; // type pattern "int i"
与i
在同一级别上声明,这意味着它不仅适用于if
,也适用于以下语句。当你复制if
:
if
给出错误CS0128:已在此范围内定义名为“i”的局部变量。
答案 1 :(得分:4)
我已将a similar question发布到Roslyn问题,并由 DavidArno 给出了答案:
很长,但你可以阅读为什么语言的所有血腥细节 设计团队选择"增强"这种语言在#12939。
TL; DR你并不是唯一一个认为变化不直观的人 与范围以前的工作方式相矛盾。可悲的是,团队 虽然不在乎,但改变仍然存在。
似乎决定这个范围将适用,所以规范现在已经过时了,这个范围很遗憾:
选项3:表达式变量按块,for,foreach和。作用域 using语句,以及所有嵌入语句:
这里的嵌入式语句的含义是用作的语句 另一个语句中的嵌套语句 - 除了块内。从而 if语句的分支,while,foreach等的主体。 将被视为嵌入式。
结果是变量总会逃脱 一个if,但从来没有它的分支。好像你把所有的卷曲都放在了 那些地方你应该"。
结论
虽然有点微妙,但我们会采用选项3.它会很好 平衡:
它支持关键方案,包括非Try方法的vars,as 以及保镖if语句中的模式和变量。它没有 导致恶劣和反直觉的多层次溢出"。它 确实意味着您将获得范围比当前更多的变量 限制性制度。这似乎并不危险,因为确定 分配分析将阻止未初始化的使用。但是,它 防止变量名重用,并导致更多名称 显示在完成列表中。这似乎是一个合理的权衡。