为什么不能在嵌套的本地作用域中声明重复的variables名?
基于这个最近的问题 ,我不明白所提供的答案。 似乎你应该可以做这样的事情,因为他们的范围不重叠
static void Main() { { int i; } int i; }
此代码无法编译以下错误:
名为'i'的局部variables不能在这个范围内声明,因为它会给'i'赋予不同的含义,'i'已经在'子'范围内用来表示别的东西
我不认为迄今为止的答案已经相当规范的关键线。
从8.5.1节:
局部variables声明中声明的局部variables的范围是声明出现的块 。 在局部variables的局部variables声明符之前的文本位置引用局部variables是错误的。 在局部variables的范围内,声明另一个局部variables或具有相同名称的常量是编译时错误。
(强调我的)
换句话说,“later”variables的作用域包含声明之前的块的部分,即它包含了包含“early”variables的“inner”块。
你不能在声明之前的地方引用后面的variables – 但它仍然在范围之内。
“局部variables或常量variables的范围扩展到当前块的结尾,不能在当前块或任何嵌套块中声明另一个具有相同名称的局部variables。 C#3.0的简介, http ://www.amazon.com/3-0-Nutshell-Desktop-Reference-OReilly/dp/0596527578/
“块的局部variables声明空间包括任何嵌套块,因此,在嵌套块中,不可能在封闭块中声明与局部variables同名的局部variables。 variables范围,MSDN, http://msdn.microsoft.com/en-us/library/aa691107%28v=vs.71%29.aspx
另一方面,这与JavaScript和F#范围规则相反。
从C#语言规范:
块的局部variables声明空间包括任何嵌套块。 因此,在一个嵌套块中,不可能在封闭块中声明一个与本地variables同名的局部variables。
实际上,这是不允许的,因为在C#中,它们的作用域实际上是重叠的。
编辑:只是为了澄清,C#的作用域是在块级解决,而不是逐行解决。 所以,尽pipe在声明之前不能引用代码中的variables,但它的范围也一直延伸到块的开头。
这是C#中第一个版本的规则。
允许重叠的范围只会导致混淆(程序员,而不是编译器)。
所以这是被禁止的。
这不是重叠范围的问题。 在C#中,一个简单的名字在声明的块内不能超过一个。 在你的例子中,名字i
表示同一个外部块中的两个不同的东西。
换句话说,您应该能够将variables声明移到声明块的任何位置,而不会导致范围重叠。 由于将您的示例更改为:
static void Main() { int i; { int i; } }
会导致不同的variables的范围重叠,你的例子是非法的。
对于C#,ISO 23270( 信息技术 – 编程语言-C# ),§10.3( 声明 )说:
每个块 , switch-block , for-statement , foreach-statement或using-statement为局部variables和局部常量创build一个声明空间,称为局部variables声明空间 。 名称通过局部variables声明和局部常量声明引入到这个声明空间中。
如果块是实例构造函数,方法或运算符声明的主体,或者索引器声明的get或set访问器,则在此声明中声明的参数是块的局部variables声明空间的成员。
如果块是generics方法的主体,则在这种声明中声明的types参数是块的局部variables声明空间的成员。
局部variables声明空间的两个成员具有相同的名称是错误的。 局部variables声明空间和嵌套局部variables声明空间包含具有相同名称的元素是错误的。
[ 注意:因此,在嵌套块中,不可能在封闭块中声明局部variables或常量与局部variables或常量具有相同的名称。 只要两个块都不包含另一个嵌套块,就可以包含同名的元素。 尾注 ]
所以
public void foobar() { if ( foo() ) { int i = 0 ; ... } if ( bar() ) { int i = 0 ; ... } return ; }
是合法的,但是
public void foobar() { int i = 0 ; if ( foo() ) { int i = 0 ; ... } ... return ; }
是不合法的。 我个人觉得这个限制比较烦人。 我可以看到发出一个关于范围重叠的编译器警告,但编译错误? 太多的腰带和吊带,恕我直言。 我可以看到一个编译器选项和/或编译指示的优点,尽pipe(可能是-pedantic
/的/ -practical
, #pragma pedantic
vs #pragma practical
, B^)
)。
我只是把它编译成C和C ++。 我没有收到错误消息,所以它似乎是有效的语法。
你的问题被标记为.net和作为c。 这应该被标记为C#? 这种语言可能与C有不同的规则
在C中,你需要把所有的variables声明放在块的开头。 他们需要在开幕之后直接来到这个区块的任何其他陈述之前。
那么你可以做什么来编译它是这样的:
static void Main() { { int i; } { int i; } }
这是你从MSDN .NET文档中的答案:
…块的局部variables声明空间包括任何嵌套块。 因此,在一个嵌套块中,不可能在封闭块中声明一个与本地variables同名的局部variables。
- 在C#中,new object()和new {}有什么区别?
- 在EntityFramework.dll中发生未处理的“System.TypeInitializationException”typesexception
- 如何在.NET中显示错误和警告消息框/如何自定义MessageBox
- 在“foreach”循环中修改列表的最好方法是什么?
- MarshalByRefObject是否特别?
- 使用Windows窗体在button上显示工具提示
- 在.NET中本地存储数据的最佳方法(C#)
- 我可以做什么来解决在SQL Server Compact Edition数据库上的LINQ to SQL中的“行未find或更改”exception?
- GMail SMTP通过所有端口上的C#.Net错误