6

say I have:

 class Test
 {
      public static int Hello = 5;
 }

This obviously works:

 int j = Test.Hello;

But why should this not work?

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

The instance could not have a member equally named, so I don't see how this could be ambiguous or unresolvable for a compiler.

Anyone any idea why this is?

EDIT: Is there any other technical reason why this should be OTHER than the language designers choosing this for readability/clarity/aesthetics/etc?

Toad
  • 15,593
  • 16
  • 82
  • 128
  • An interesting brain twister: What will happen if you name your instance variable `Test` (i.e. use the same name as the class)? Check the answer here: http://blogs.msdn.com/ericlippert/archive/2009/07/06/color-color.aspx – Dirk Vollmar Mar 19 '10 at 12:29
  • 1
    with C# 3.0's extension methods you can obtain exactly this. Statics that can be called as instance methods. Works only for methods not props though. – Adrian Zanescu Mar 19 '10 at 12:42
  • @AZ: Just this weekend I read about them and they do indeed exactly as what I describe. Apparently the plus points outweigh the negative points. – Toad Mar 22 '10 at 13:02
  • A similar construct would have worked in C++ though. – Lazer Jul 20 '10 at 15:14

5 Answers5

14

Another angle:

Suppose this were possible. What would you then like the result to be when a static member is accessed through an instance variable which is null ? Would you like a null reference exception (but why, since no instance should be required to obtain a static member)? Or would you like it to work (in which case you would have the odd situation that some invocations on this instance variable worked, but some didn't)? Either way has problems.

AakashM
  • 62,551
  • 17
  • 151
  • 186
  • 1
    @aakashm: great answer. This was the explanation I was looking for. Clearly one doesn't want to have such a situation. – Toad Mar 19 '10 at 12:32
  • @aakashm: Just read in John Skeets book yesterday that Extension methods are static, but appear to be instance methods of a class. In this case it is valid to call (what looks like) an instance method, on a class which is null. (and is silently transformed into a static call) – Toad Mar 22 '10 at 13:00
11

Remember what static methods (or properties, or fields) are: They belong to a class, and not to any particular instance of that class. Because of that, they are shared across all instances.

Therefore, it is only logical that static members must be accessed via the class name and not through an object. It's well true that the C# language could have been designed differently in this respect... but it wasn't.

stakx - no longer contributing
  • 83,039
  • 20
  • 168
  • 268
  • I couldn't have said it better +1 – Brian Mar 19 '10 at 12:21
  • So... if I translate what you are saying: there is no reason to not allow it through an instance name, OTHER than to make it clear for the reader(and writer) of the code that we are accessing a static member right? – Toad Mar 19 '10 at 12:22
  • 1
    @reinier If you _really_ need this, you could always just create a trivial function/property in the class that can return/set hello? – wasatz Mar 19 '10 at 12:26
  • Yep, also see Eric Lippert's remark (http://stackoverflow.com/questions/1980207/static-shared-in-vb-net-and-c-visibility/1980709#1980709): "On the C# design team, we highly value a language definition which makes illegal patterns that look suspicious; since there's no meaning to passing an instance as the receiver to a static method (unless computing the receiver expression causes a side effect) then why allow the user to type meaningless code?" – Dirk Vollmar Mar 19 '10 at 12:26
  • @divo: they might as well have allowed it since it's obvious what someone wants/means. I do agree that something is lost in translation (the fact that the type is static)..but then again, I also don't see if the type is a property or field, or if it is an int or byte. – Toad Mar 19 '10 at 12:29
  • @reinier: The point is not that you should *see* from the call that the method is static, the point is that it has *no meaning* to pass an instance as the receiver to a static method. If you prefer a language that treats code "the way you meant it to work" then you might prefer the philosophy of VB over C#. – Dirk Vollmar Mar 19 '10 at 16:13
  • @divo: Extension methods (which appear to be instance methods) are by definition ALSO static. So your point about seeing if a method is static or an instance method doesn't hold! – Toad Mar 22 '10 at 12:58
1

I think of it as defensive language design: if you mistakenly declare a property as static, and then are setting/getting it from various instances when you assumed it was an instance property, you could get all kinds of evil side effects without any really obvious indication of what's wrong.

By requiring the developer to use the class name to access the static property, it makes it clear that it is not an instance property, and requires the developer to be explicit when coding that they really did want to access this as a static property.

D'Arcy Rittich
  • 167,292
  • 40
  • 290
  • 283
1

"Is there any other technical reason why this should be OTHER than the language designers choosing this for readability/clarity/aesthetics/etc?"

The only other reason that I can think of would be that it creates extra hoops for your compiler to jump through (not that this is a huge concern). If static method calls could be accessed by instances, the instances would have to be storing all the static offsets or the compiler would have to perform an extra step where it looked for a static method with the same signature on the class when it was unable to locate a non-static method on the instance.

heisenberg
  • 9,665
  • 1
  • 30
  • 38
0

You can read the detailed explanation of the static keyword on MSDN but I think it is best explained by this quote

While an instance of a class contains a separate copy of all instance fields of the class, there is only one copy of each static field.

I believe this might be routed in memory addresses and offsets used by the compiler. From what I remember in my compiler course in school the location of your instance variables would be stored as offsets from the first memory location where the object is stored. Since there is only one copy of the static field it would never be a fixed offset to access the value of the static field.

Regarding the ambiguity of the names, this might be as simple as name collision within something such as a symbol table. However, there could easily be deeper technical consideration.

Richard McGuire
  • 10,780
  • 8
  • 31
  • 34
  • @rich: I understand the difference between a static and instance variable. I was just wondering why a static variable could only be accessed through the Classname (so if there was some deep underlying problem with this, or if it was just a choice). given aakashm's answer I see the problem with it – Toad Mar 19 '10 at 12:37