kem*_*002 7 c# language-design switch-statement
有没有理由我错过了case语句中的块不被视为块级声明空间?
我尝试时不断收到错误(变量已经声明)
case x:
  var someVariable = 42;
break;
case y: 
   var someVariable = 40;
break;
但我能做到
case x:
   try{var someVariable = 42;}catch{} 
break;
case y: 
    try{var someVariable = 40;}catch{}
break;
如果C#允许通过语句,那就没有意义,但事实并非如此,我想不出你可以在case语句中声明变量并在该块之外使用它的场景.
Eri*_*ert 32
更新:这个问题被用作这篇博文的灵感来源; 看到它的更多细节.
http://ericlippert.com/2009/08/13/four-switch-oddities/
感谢有趣的问题.
在其他各种答案中存在许多混淆和错误陈述,其中没有一个真正解释了为什么这是非法的.我将尝试确定.
首先,要严格正确,"范围"是用来描述问题的错误词.巧合的是,我上周写了一篇关于"范围"错误使用的博客文章; 这将在我的迭代器块系列之后发布,它将在整个7月份运行.
正确使用的术语是" 声明空间 ".声明空间是一个代码区域,其中不能声明两个不同的东西具有相同的名称.这里描述的场景是交换部分没有定义声明空间这一事实的症状,尽管开关块确实如此. 由于OP的两个声明属于同一声明空间并且具有相同的名称,因此它们是非法的.
(是的,switch块也定义了一个范围,但这个事实与问题无关,因为问题是关于声明的合法性,而不是标识符查找的语义.)
一个合理的问题是"为什么这不合法?" 一个合理的答案是"好吧,为什么要这样"?你可以用两种方式之一.这是合法的:
switch(y)
{
case 1:  int x = 123; ... break;
case 2:  int x = 456; ... break;
}
或者这是合法的:
switch(y)
{
case 1:  int x = 123; ... break;
case 2:  x = 456; ... break;
}
但你不可能两种方式.C#的设计者选择第二种方式似乎是更自然的方式.
这个决定是在1999年7月7日做出的,差不多十年前.当天笔记中的评论非常简短,只是说明" 一个开关案例不会创建自己的声明空间 ",然后提供一些示例代码,显示哪些有效,哪些无效.
为了更多地了解这个特定日子里设计师的想法,我不得不让很多人对他们十年前的想法感到不满 - 而且他们对最终是一个微不足道的问题有所了解.我不打算这样做.
简而言之,没有特别令人信服的理由选择这种或那种方式; 两者都有优点.语言设计团队选择了一种方式,因为他们必须选择一种方式; 他们选择的那个对我来说似乎很合理.
啊 - 你没有通过,但你可以使用转到跳转到另一个标记的案例块.因此,块必须在相同的范围内.
你还可以这样做:
case x:
  {var someVariable = 42;}
break;
case y: 
   {var someVariable = 40;}
break;
本质上,大括号创建了词法范围,因此如果没有大括号,someVariable 会被加载到符号表中两次。我相信这种选择可能只是为了避免混淆,并且可能是为了避免增加符号表构建的复杂性。
| 归档时间: | 
 | 
| 查看次数: | 1679 次 | 
| 最近记录: |