Why Shouldn't You Access a Shared/static Member Through An Instance Variable?
Here's an example of what I'm talking about...
Public Class Sample1
开发者_StackOverflow Public Shared Function MyValue() As Integer
Return 0
End Function
Public Sub Code()
Dim ThisIsBad = Me.MyValue
Dim ThisIsGood = Sample1.MyValue
End Sub
End Class
Me.MyValue
gives a warning in VB.NET and (the equivalent code gives) an error in C#. Is there a particular reason for this? I find it more intuitive/natural to access the shared function using 'Me.MyValue' - but I avoid it to keep my warnings at 0.
Did someone else just decide 'Nah, it makes more sense to do it the other way' or is there some technical reason I don't understand?
EDIT:
Thanks everyone. I was thinking of it wrong, more like a 'sub class' in OOP. Even if something is declared in the base class, you access it through the instance you have. But that relationship is not the same with shared or static.
Static members by definition are declared at the class level, not the instance level, and so accessing a static member using this
(or me
in VB) doesn't really feel right (and isn't right in C#)
Saying this.something
(or me.something
) implies you are accessing "something" that's particular to that specific instance, while, again, static members are shared throughout all instances of that class.
It's misleading for the reader of your code.
Code should be written to be read and understood by another programmer, wo doesn't know every detail of the project. Accessing a static variable through an instance makes it look like an instance member - you'd have to check the declaration to see you are mistaken.
That "other programmer" might as well be you after half a year.
Me
points to the current instance of Sample1
, while MyValue
does belong to the class itself. Thus, it seems fine to me that VB.NET warns you.
By the way, Java does it in the same way:
Thread.currentThread().sleep(1000); // warning, as sleep is static
Thread.sleep(1000); // correct
Cheers Matthias
The static members/methods
operates at class level
( i.e. behavior that is independent of any object instance) and object's members/methods
operates at instance level
, so they have two different identities:
- http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.80).aspx
More than likely the compiler is protecting you from making a mistake in the case where you have an instance and static member of the same name.
class X {
static public void X1 ()
{
Console.WriteLine ("Static");
}
public void X1 (bool x1 = false)
{
X1(); // Which one is this calling?
Console.WriteLine ("Instance");
}
}
void Main()
{
X.X1 (); // Static
new X ().X1 (false); // Instance
}
results in:
- Static
- Static
- Instance
You cannot access class level fields by this
reference and you cannot access object level fields by class reference it makes perfect sense.
If you were to access class level field by this
pointer you could end up with following weird code
objA.StaticVariable=1;
objB.StaticVariable=2;
which could mislead someone that we were actually editing different properties or fields, but if they are access by class name
Class.StaticVariable=1
Class.StaticVariable=2
its clear that we are editing the same thing.
Also in memory static fields are stored in completely different place (close to Type
object) than object fields so I think its super clear difference.
The real question is - why its not an error in VB.NET. I would guess that the answer is taht VB was inheriting some of old non .NET VB features which wasnt very type safe and its a weird result of such inheritance.
精彩评论