为什么不通过实例变量访问共享/静态成员?

时间:2011-03-03 15:58:50

标签: c# .net vb.net

这是我正在谈论的一个例子......

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在VB.NET中发出警告,并且(等效代码给出)C#中的错误。这有什么特别的原因吗?我发现使用'Me.MyValue'访问共享函数更直观/自然 - 但我避免它将我的警告保持为0。

其他人是否只是决定'Nah,从另一个角度来做更有意义'还是有一些我不理解的技术原因?

编辑:

谢谢大家。我认为它错了,更像是OOP中的“子类”。即使在基类中声明了某些内容,也可以通过您拥有的实例访问它。但这种关系与共享或静态不同。

6 个答案:

答案 0 :(得分:7)

根据定义,静态成员是在级别而不是实例级别声明的,因此使用this(或VB中的me)访问静态成员并不会真的觉得对(在C#中不对)

this.something(或me.something)意味着您正在访问特定于该特定实例的“某些内容”,同时,静态成员在所有实例中共享那个班。

答案 1 :(得分:3)

这对您的代码的读者有误导性。

代码应编写为由另一个程序员阅读和理解,我不知道项目的每个细节。通过实例访问静态变量使它看起来像一个实例成员 - 你必须检查声明,看你错了。

半年后,“其他程序员”也可能是你。

答案 2 :(得分:2)

Me指向Sample1当前实例,而MyValue确实属于本身。因此,VB.NET警告你似乎很好。

顺便说一下,Java以同样的方式做到了:

Thread.currentThread().sleep(1000); // warning, as sleep is static
Thread.sleep(1000); // correct

干杯 的Matthias

答案 3 :(得分:2)

静态members/methodsclass level运行(即独立于任何对象实例的行为),object's members/methodsinstance level运行,因此它们有两种不同的身份:   - http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.80).aspx

答案 4 :(得分:1)

在您拥有同名实例和静态成员的情况下,编译器很可能会保护您不会出错。

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
}

结果:

  • 静态
  • 静态
  • 实例

答案 5 :(得分:1)

您无法通过this引用访问类级别字段,并且您无法通过类引用访问对象级别字段,这非常有意义。

如果您要通过this指针访问类级别字段,则可能会遇到以下奇怪的代码

objA.StaticVariable=1;
objB.StaticVariable=2;

可能会误导我们实际编辑不同属性或字段的人,但是如果他们是按类名访问的话

Class.StaticVariable=1
Class.StaticVariable=2
很明显我们正在编辑同样的事情。

同样在内存中,静态字段存储在与对象字段完全不同的位置(接近Type对象),因此我认为它的区别非常明显。

真正的问题是 - 为什么它不是VB.NET中的错误。我猜这个答案就是VB继承了一些非.NET VB的旧功能,这些功能不是很安全,而且是继承的奇怪结果。

相关问题