And*_*lon 11 c# pattern-matching c#-7.0
在Roslyn模式匹配规范中,它指出:
模式变量的范围如下:
如果模式出现在if语句的条件中,则其作用域是if语句的条件和受控语句,而不是其else子句.
然而,最新的Microsoft"What's new" 帖子和演示文稿显示了这个例子:
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));
}
Run Code Online (Sandbox Code Playgroud)
其中显示了在模式匹配i的if级别范围之外使用的模式匹配变量.
这是一个疏忽,还是从规范中改变了范围?
来自同一个文档:
模式引入的变量——类似于前面描述的输出变量
所以实际上这段代码:
if (!(o is int i)) return; // type pattern "int i"
Run Code Online (Sandbox Code Playgroud)
或多或少等于:
int i;
if (!(SomeParsingOn(o, out i))) return; // type pattern "int i"
Run Code Online (Sandbox Code Playgroud)
这意味着i是在与 相同的级别上声明的if,这意味着它不仅在 范围内if,而且在以下语句的范围内。当您复制以下内容时,可以看出这是真的if:
if (!(o is int i)) return; // type pattern "int i"
if (!(o is int i)) return; // type pattern "int i"
Run Code Online (Sandbox Code Playgroud)
给出错误 CS0128:名为“i”的局部变量已在此范围中定义。
我发布了与罗斯林问题类似的问题,DavidArno给出了答案:
很长,但是您可以在#12939中阅读有关语言设计团队选择以这种方式“增强”语言的所有详细信息。
TL; DR并非只有您一个人认为这种变化与示波器的工作方式不直观且矛盾。不幸的是,车队不在乎,变化将一直存在。
似乎已决定采用此范围,因此该规范现在已过时,可悲的是此范围仍然存在:
选项3:表达式变量的作用域是块,for,foreach和using语句,以及所有嵌入式语句:
嵌入式语句在这里的意思是,它被用作另一个语句中的嵌套语句-除了块内。因此,if语句的分支,while,foreach的主体等都将被视为嵌入的。
结果是变量将始终转义if的条件,但不会转义其分支。好像您在所有“应该放置”的地方都放置了卷发器一样。
结论
虽然有些微妙,但我们将采用选项3。它达到了很好的平衡:
它启用了关键方案,包括用于非Try方法的out var,以及在bouncer if语句中的模式和out var。它不会导致极端和违反直觉的多层次“溢出”。这确实意味着您将获得比当前限制性制度更多的范围变量。这似乎并不危险,因为确定的分配分析将防止未初始化的使用。但是,它阻止了变量名的重用,并导致更多名称显示在完成列表中。这似乎是一个合理的权衡。