繁体   English   中英

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

[英]why can't a static member be reached through an instance name?

说我有:

 class Test
 {
      public static int Hello = 5;
 }

这显然有效:

 int j = Test.Hello;

但为什么这不起作用?

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

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

任何人都知道为什么会这样?

编辑:有没有任何其他技术原因,为什么这应该是语言设计师选择这个为可读性/清晰度/美学/等?

另一个角度:

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

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

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

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

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

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

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

您可以在MSDN上阅读静态关键字的详细说明,但我认为最好用这句话来解释

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM