为什么不能通过实例名称访问静态成员?

时间:2010-03-19 12:13:36

标签: c# .net compiler-construction static

说我有:

 class Test
 {
      public static int Hello = 5;
 }

这显然有效:

 int j = Test.Hello;

但为什么这不起作用?

 Test test = new Test();
 int j = test.Hello;

实例没有一个同名的成员,所以我看不出这对于编译器来说是多么模糊或不可解析。

有人知道为什么会这样吗?

编辑: 除了语言设计者为了可读性/清晰度/美学/等而选择它之外,还有其他任何技术原因吗?

5 个答案:

答案 0 :(得分:14)

另一个角度:

假设 可能。当通过null的实例变量访问静态成员时,您会想要的结果是什么?您想要一个空引用异常(但为什么,因为不需要实例来获取静态成员)?或者你希望它能工作(在这种情况下你会遇到奇怪的情况,这个实例变量的一些调用工作,但有些没有)?无论哪种方式都有问题。

答案 1 :(得分:11)

记住静态方法(或属性或字段)是什么:它们属于一个类,而不属于该类的任何特定实例。因此,它们在所有实例中共享。

因此,通过类名而不是通过对象访问静态成员是合乎逻辑的。在这方面,C#语言的设计可能不同......但事实并非如此。

答案 2 :(得分:1)

我认为它是防御性语言设计:如果你错误地将属性声明为静态,然后在你认为它是一个实例属性时从各种实例设置/获取它,你可以得到各种邪恶的副作用任何真正明显的错误迹象。

通过要求开发人员使用类名来访问静态属性,它清楚地表明它不是一个实例属性,并且要求开发人员在编码时要明确他们确实想要以静态方式访问它属性。

答案 3 :(得分:1)

“除了语言设计师为了可读性/清晰度/美学/等而选择此项外,还有其他任何技术原因吗?”

我能想到的另一个原因是它为你的编译器创造了额外的环节(不是这是一个巨大的问题)。如果实例可以访问静态方法调用,则实例必须存储所有静态偏移量,否则编译器必须执行额外的步骤,以便在类无法访问时在类中查找具有相同签名的静态方法在实例上找到非静态方法。

答案 4 :(得分:0)

您可以阅读static keyword on MSDN的详细说明,但我认为最好通过此引文解释

  

虽然类的实例包含该类的所有实例字段的单独副本,但每个静态字段只有一个副本。

我相信这可能会在内存地址和编译器使用的偏移量中进行路由。根据我在学校编译器课程中记得的内容,实例变量的位置将存储为存储对象的第一个内存位置的偏移量。由于静态字段只有一个副本,因此永远不会是固定偏移量来访问静态字段的值。

关于名称的模糊性,这可能就像符号表之类的名称冲突一样简单。但是,可以很容易地进行更深入的技术考虑。