首先,我要说我之前从未使用过C#,而且我对此并不了解。
我正在学习Sebesta的“编程语言概念第9版”一书中的“编程语言”考试。在我从“范围声明顺序(第246页)”中阅读以下摘录后,我有点疑惑:
“...例如,在C99,C ++,Java中,所有局部变量的范围都是从它们的声明到那些声明出现的块的末尾。但是,在C#中任何变量的范围在块中声明的是整个块,无论块中声明的位置如何,只要它不在嵌套块中。方法也是如此。注意C#仍然需要所有变量在使用之前都要声明。因此,尽管变量的范围从声明扩展到块的顶部或声明出现的子程序,但变量仍然不能在其声明之上使用“
为什么C#的设计师做出这样的决定?这种不寻常的决定是否有任何具体的原因/优势?
答案 0 :(得分:9)
查看Eric Lippert关于declaration spaces的帖子,其中提供了更多这些规则的背景信息。
我通常会在链接到博客帖子时引用最相关的位,但我认为这些在一起阅读时确实给出了更好的答案。
希望他会流行并给出一个很好的总结。
答案 1 :(得分:5)
这会阻止您执行
之类的操作void Blah()
{
for (int i = 0; i < 10; i++)
{
// do something
}
int i = 42;
}
原因是,如果你必须移动代码,它会引入细微的错误。如果你在循环之前需要i
,那么你的循环就会被打破。
答案 2 :(得分:3)
减少混淆的好处的一个例子是,如果在变量声明之上有一个嵌套块,则变量声明将生效并阻止嵌套块声明具有相同名称的变量。
答案 3 :(得分:3)
来自C# Spec
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
}
}
局部变量的作用域规则旨在保证表达式上下文中使用的名称的含义在块中始终相同。如果局部变量的范围仅从其声明扩展到块的末尾,那么在上面的示例中,第一个赋值将分配给实例变量,第二个赋值将分配给局部变量,可能导致如果稍后重新安排块的语句,则编译时错误。
答案 4 :(得分:1)
这并不奇怪。就变量而言,它比Java / C ++更强制地执行唯一命名。
答案 5 :(得分:0)
Eric Lippert对this related question的回答可能会有所帮助。
正如Anthony Pegram先前所说,C#强制执行此规则,因为有些情况下重新排列代码会导致细微的错误,从而导致混淆。