views:

163

answers:

5

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?

+10  A: 

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
I couldn't have said it better +1
used2could
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
@reinier If you _really_ need this, you could always just create a trivial function/property in the class that can return/set hello?
wasatz
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?"
0xA3
@wasatz: I don't need it.... I'm just curious as to why
Toad
@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
@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#.
0xA3
@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
+9  A: 

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
@aakashm: great answer. This was the explanation I was looking for. Clearly one doesn't want to have such a situation.
Toad
@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
A: 

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 C. McGuire
@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
A: 

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.

RedFilter
A: 

"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.

kekekela