2

为什么我无法访问行中的隐藏实例变量 a (int gimmeValue = shinyNewBObject.a;) ?我知道我可以使用 base 关键字来访问实例 a。但是,我认为编译器会使用 shinyNewBObject 中的对象引用来排除静态变量。如果排除了 a 的静态版本,则 a 的实例版本将变得不隐藏,因此可以访问。

这里发生了什么?编译器是否创建了程序集中所有 a 身份的列表并排除了实例变量,因为它在排除另一个 a 因为它是静态的之前是隐藏的?

class A
{
    public int a;
}

class B : A
{
    new public static int a;

    public void m()
    {
        B shinyNewBObject = new B();
        int gimmeValue = shinyNewBObject.a; //Error
        gimmeValue = base.a;
    }
}
4

2 回答 2

4

我不完全确定 C# 规范的哪一部分规定了为什么当基类型变量被子类中的静态字段遮挡时它不允许您访问它,但要解决它,您可以强制转换为A

int gimmeValue = ((A)shinyNewBObject).a; 
于 2012-06-17T17:35:55.137 回答
1

我想我找到了答案:

我需要查看规范(7.4)的成员查找部分。

“查找规则的效果只是派生成员隐藏了具有相同名称或签名的基础成员。这种单继承查找永远不会模棱两可。”

我认为当编译器考虑 aobj.a 时会发生什么 aobj 暂时被忽略而只考虑 a 。

编译器转到 A 类定义,该类定义隐式或显式地具有所有静态和实例成员,并看到两个 a 成员。两者都可以基于 (3.5) 访问,因此它们属于可能性集合。然后隐藏变量被删除,留下静态变量。

最后考虑'aobj'并发生错误,因为实例引用无法访问静态变量。

我的故事可能有一些问题。如果是这样,请纠正我,因为我做了一些猜测。

于 2012-06-17T20:18:45.463 回答