让我们来看下面的代码:
class Foo
{
string bar;
public void Method()
{
if (!String.IsNullOrEmpty(this.bar))
{
string bar = "Hello";
Console.Write(bar);
}
}
}
这将编译通过,一切都很好。然而,现在让我们去掉 this.
前缀:
class Foo
{
string bar;
public void Method()
{
if (!String.IsNullOrEmpty(bar)) // <-- Removed "this."
{
string bar = "Hello";
Console.Write(bar);
}
}
}
在这种情况下,我收到编译器错误。我同意这是一个错误,然而让我困惑的是错误发生在以下行上:string bar = "Hello";
带有以下信息:
无法在此作用域中声明名为“bar”的局部变量,因为它将赋予“bar”不同的含义,而“bar”已经在“父级或当前”作用域中用于表示其他内容。
从我对编译器的理解来看,bar
的声明会被提升到 Method()
方法的顶部。但是,如果是这种情况,则下面这行代码:
if (!String.IsNullOrEmpty(bar))
应该考虑到歧义问题,因为bar
可能是对实例字段的引用,也可能是对尚未声明的局部变量的引用。
我认为,删除this.
会导致另一行编译错误似乎很奇怪。换句话说,在作用域中声明本地变量bar
是完全有效的,只要之前没有进行过潜在的歧义引用bar
(请注意,如果我注释掉if (!String.IsNullOrEmpty(bar))
,则错误将消失)。
这听起来有点吹毛求疵,那么你的问题是什么?
我的问题是,为什么编译器允许在作用域内先声明一个模棱两可的变量引用,但随后标记声明本身为冗余。难道不应该将String.IsNullOrEmpty()
中对bar
的模棱两可引用作为更精确的错误位置吗?在我的示例中,当然很容易发现,但当我在实际工作中遇到此问题时,引用距离很远,更难以追踪。
this.
会使第二个引用编译! - Gabebar
时,所有未来的引用都必须引用那个实体。因此,局部变量bar
的新声明是一种违规行为。很有道理。 - Mike Christensen