2012-06-17 55 views
2

我怎么不能访问行中隐藏的实例变量a(int gimmeValue = shinyNewBObject.a;)?我知道我可以使用base关键字来访问实例a。不过,我认为编译器会使用shinyNewBObject中的对象引用来排除静态变量。如果排除了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; 
    } 
} 
+0

实例变量不能是静态的 –

+0

@AkashKava,它之前的格式很差,但是实例字段是'A'中的。 –

+0

对不起格式差,我认为该网站做到了这一点 – greenonion

回答

1

我想我找到了答案:

我需要看看说明书(7.4)的成员查找部分。

“查找规则的效果只是派生成员隐藏了具有相同名称或签名的基本成员,这种单一继承查找从不含糊。”

我认为当编译器考虑aobj.a会发生什么情况,aobj会暂时被忽略,只是一个被考虑。

编译器转到A类定义,该类定义隐式或显式地包含所有静态和实例成员,并看到这两个成员。两者都可以基于(3.5)进行访问,因此他们可以进入一系列可能性。然后隐藏的变量被移除,留下静态的变量。

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

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

4

我不完全知道什么是C#规范的一部分规定,为什么它不会让你访问基类型的变量时,它通过在子类中静态字段遮挡,但要解决它,你可以只是转换为A

int gimmeValue = ((A)shinyNewBObject).a; 
+0

显然我不能发布我自己的答案,因为我没有足够的积分或任何 – greenonion

+1

我想我找到了答案: 我需要看看成员查阅规范部分(7.4)。 “查找规则的作用就是派生成员隐藏具有相同名称或签名的基本成员,这种单一继承查找从不含糊。” 我认为编译器认为aobj.a会发生什么情况,现在忽略aobj,只是考虑了a。 – greenonion

+1

编译器转到A类定义,该类定义隐式或显式地包含所有静态和实例成员,并看到两个成员。两者都可以基于(3.5)进行访问,因此他们可以进入一系列可能性。然后隐藏的变量被移除,留下静态的变量。 最后会考虑'aobj',并且会发生错误,因为实例引用无法访问静态变量。 我的故事可能存在一些问题。如果是这样,请纠正我,因为我做了一些猜测。 – greenonion