关于C#变量范围与其他语言的问题
首先,让我说我之前从未使用过C#,而且我对此并不了解。
我正在和Sebesta的“编程语言概念第9版”一书中学习我的“编程语言”考试。 在我从“范围声明顺序(第246页)”中阅读以下摘录后,我有点疑惑:
“…例如,在C99,C ++,Java中,所有局部变量的范围都是从它们的声明到那些声明出现的块的末尾。 但是,在C#中,块中声明的任何变量的范围是整个块,无论块中声明的位置如何,只要它不在嵌套块中。方法也是如此。 注意C#仍然要求在使用它们之前声明所有变量。因此,尽管变量的范围从声明扩展到该声明出现的块或子程序的顶部,该变量仍然不能在其声明之上使用 “
为什么C#的设计师会做出这样的决定? 这种不寻常的决定有什么特定的理由/优势吗?
看看Eric Lippert关于声明空间的post,它们为这些规则提供了更多背景知识。
我通常会在链接到博客post时引用最相关的位,但我认为这些在一起阅读时确实给出了更好的答案。
希望他会流行并给出一个很好的总结。
这可以防止你做某些事情
void Blah() { for (int i = 0; i < 10; i++) { // do something } int i = 42; }
原因是,如果必须移动代码,它会引入细微错误的可能性。 如果你在循环之前需要i
,现在你的循环被打破了。
减少混淆的一个好处是,如果在变量声明之上有一个嵌套块,则变量声明将生效并阻止嵌套块声明具有相同名称的变量。
来自C#规范
class A { int i = 0; void F() { i = 1; // Error, use precedes declaration int i; i = 2; } void G() { int j = (j = 1); // Valid } void H() { int a = 1, b = ++a; // Valid } }
局部变量的作用域规则旨在保证表达式上下文中使用的名称的含义在块内始终相同。 如果局部变量的范围仅从其声明扩展到块的末尾,那么在上面的示例中,第一个赋值将分配给实例变量,第二个赋值将分配给局部变量,可能导致如果稍后重新排列块的语句,则编译时错误。
这并不奇怪。 就变量而言,它比Java / C ++更强制地执行唯一命名。
Eric Lippert对这个相关问题的回答可能会有所帮助。
正如Anthony Pegram先前所说,C#强制执行此规则,因为有些情况下重新排列代码会导致细微的错误,从而导致混淆。
- 使用LINQ访问表中的第一个元素时出现SQLite错误
- 使用reflection通过从setter调用的方法获取属性的属性
- C# – 排序基元数组并跟踪其指数的最快方法
- LINQ to Entities / LINQ to SQL:在查询理解过程中从服务器(可查询)切换到客户端(可枚举)?
- 在方法签名中使用async关键字在Web Api端点中返回Task
- 为什么我不能从List 转换为List ?
- WinRT应用程序和区域设置。 根据用户的区域设置格式化日期和数字的正确方法?
- 在C#AccesViolationException中调用Pocketsphinx
- EventLogQuery:如何形成查询字符串?