在变量范围方面,C#非常适合挑选.它怎么可能接受这个代码:
class Program
{
int x = 0;
void foo()
{
int x = 0;
x = 1;
Console.WriteLine(x);
}
}
Run Code Online (Sandbox Code Playgroud)
如果你问我,这是一个明显的命名冲突.编译器(VS 2010)仍然接受它.为什么?
Eri*_*ert 18
C#名称隐藏的规则非常复杂.该语言允许你提到的情况,但不允许许多类似的情况.看到
http://ericlippert.com/2009/11/02/simple-names-are-not-so-simple/
有关这个复杂主题的一些信息.
为了解决您的具体问题:编译器当然可以检测到该冲突.事实上,它确实发现了这种冲突:
class P
{
int x;
void M()
{
x = 123; // The author intends "this.x = 123;"
int x = 0;
}
}
Run Code Online (Sandbox Code Playgroud)
等效的C++程序将是合法的C++,因为在C++中,局部变量在声明时就进入了范围.在C#中,局部变量在整个块中都在范围内,并且在声明之前使用它是非法的.如果你尝试编译这个程序,你会得到:
error CS0844: Cannot use local variable 'x' before it is declared.
The declaration of the local variable hides the field 'P.x'.
Run Code Online (Sandbox Code Playgroud)
请参阅:本地声明隐藏该字段.编译器知道它.那么为什么在你的情况下隐藏一个字段不是错误?
让我们假设为了论证它应该是一个错误.这也应该是一个错误吗?
class B
{
protected int x;
}
class D : B
{
void M()
{
int x;
}
}
Run Code Online (Sandbox Code Playgroud)
字段x是来自B的继承的D的成员.所以这也应该是一个错误,对吧?
现在假设您有这个由Foo Corporation制作的程序:
class B
{
}
Run Code Online (Sandbox Code Playgroud)
这个程序由Bar Corporation制作:
class D : B
{
void M()
{
int x;
}
}
Run Code Online (Sandbox Code Playgroud)
编译.现在假设Foo Corp更新他们的基类并向您发送新版本:
class B
{
protected int x;
}
Run Code Online (Sandbox Code Playgroud)
您告诉我包含名为x的局部变量的每个派生类现在都无法编译?
那太可怕了.我们必须允许局部变量来影响成员.
如果我们要允许本地人影响基类的成员,那么不允许本地人影响类的成员就显得非常奇怪.
| 归档时间: |
|
| 查看次数: |
3512 次 |
| 最近记录: |