简体   繁体   中英

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

    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

静态members/methodsclass level (即独立于任何对象实例的行为), object's members/methodsinstance level ,因此它们具有两个不同的身份: - http://msdn.microsoft.com/en-我们/库/ 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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