c# - C# 中的 Case 语句 block 级声明空间

标签 c# switch-statement language-design

是否有我遗漏 case 语句中的 block 不被视为 block 级声明空间的原因?

当我尝试时,我不断收到错误消息(变量已经被声明)

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# 允许 fall through 语句,那将是有意义的,但事实并非如此,而且我想不出可以在 case 语句中声明变量并在该 block 之外使用它的场景。

最佳答案

更新:这个问题被用作这篇博文的灵感;查看它以获取更多详细信息。

http://ericlippert.com/2009/08/13/four-switch-oddities/

感谢您提出有趣的问题。


其他各种答案中存在许多混淆和错误陈述,但都没有真正解释为什么这是非法的。我将尝试确定。

首先,严格来说,“范围”这个词用来描述问题是错误的。巧合的是,我上周写了一篇关于这种对“作用域”的误用的博文;这将在我的迭代器 block 系列之后发布,该系列将贯穿整个 7 月。

正确使用的术语是“声明空间”。声明空间是一个代码区域,其中不能将两个不同的事物声明为具有相同的名称。此处描述的场景是 switch section 没有定义声明空间这一事实的症状,尽管 switch block 定义了声明空间。 自 OP 的两个声明在同一个声明空间并且有相同的名字,它们是非法的。

(是的,开关 block 定义了一个范围,但这个事实与问题无关,因为问题是关于声明的合法性,而不是< strong>标识符查找的语义。)

一个合理的问题是“为什么这不合法?”一个合理的答案是“好吧,为什么要这样”?您可以选择两种方式之一。这是合法的:

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 日做出的,距十年前还差得很远。那天的笔记中的注释非常简短,只是简单地说明“开关盒不创建自己的声明空间”,然后给出一些示例代码来说明哪些有效,哪些无效。

为了更多地了解设计师在这一天的想法,我不得不打扰很多人了解他们十年前的想法——并且打扰他们最终是一个微不足道的问题;我不会那样做。

简而言之,没有特别令人信服的理由来选择一种方式;两者都有优点。语言设计团队选择了一种方式,因为他们不得不选择一种方式;他们选择的那个对我来说似乎很合理。

关于c# - C# 中的 Case 语句 block 级声明空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1074589/

相关文章:

oop - 为什么 Rust 不支持特征对象向上转换?

c# - 如何创建抽象类的实例?

c# - WPF Prism 在模块中加载 XML

java - 开关未按预期工作

c - break in a case with return.. 和默认

programming-languages - 如何测量一种语言的 "understandability"?

f# - 为什么 F# 中的幂运算符仅适用于 float ?

c# - 有什么方法可以保存 XmlDocument *没有*缩进和换行?

c# - 查找数字数组中丢失的元素

c - "expression must have integral type"C中的开关问题