C# 为什么不应该';您不能通过实例变量访问共享/静态成员吗?

C# 为什么不应该';您不能通过实例变量访问共享/静态成员吗?,c#,.net,vb.net,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在V

这是我所说的一个例子

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

是否有其他人刚刚决定‘不,用另一种方式做更有意义’,还是有一些技术原因我不明白

编辑:


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

静态成员根据定义是在级别声明的,而不是实例级别声明的,因此使用
this
(或者VB中的
me
)访问静态成员确实感觉不正确(在C中也不正确)


this.something
(或
me.something
)意味着您正在访问该特定实例特有的“某物”,同时,该类的所有实例都共享静态成员。

me
指向
示例1的当前实例,而
MyValue
确实属于类本身。因此,在我看来,VB.NET警告您是好的

顺便说一句,Java也是这样做的:

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

这会误导代码的读者

代码的编写应该让其他程序员阅读和理解,因为我们不知道项目的每一个细节。通过实例访问静态变量会使其看起来像实例成员—您必须检查声明以确定是否出错


半年后,那个“其他程序员”可能就是你了。

如果你有一个同名的实例和静态成员,编译器很可能是在保护你不犯错误

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
}
结果:

  • 静止的
  • 静止的
  • 实例

静态
成员/方法
类级别运行
(即独立于任何对象实例的行为),而
对象的成员/方法
实例级别运行
,因此它们具有两个不同的标识:
-

您不能通过
引用访问类级字段,也不能通过类引用访问对象级字段。这非常有意义

若您要通过
这个
指针访问类级别字段,那个么您可能会得到以下奇怪的代码

objA.StaticVariable=1;
objB.StaticVariable=2;
这可能会让人误以为我们实际上在编辑不同的属性或字段,但如果它们是通过类名访问的

Class.StaticVariable=1
Class.StaticVariable=2
很明显,我们正在编辑相同的内容

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


真正的问题是-为什么它不是VB.NET中的错误。我猜答案是,VB继承了一些旧的非.NET VB特性,这些特性不是非常类型安全的,这是这种继承的奇怪结果。

。MyValue函数不属于任何一个实例;因此,应该在单个实例的边界之外访问它。试图使用C#等效的me.MyValue会导致编译器错误,因此即使VB允许使用,也不好。@KeithS-你是想把它作为答案还是对我答案的评论?评论。我本来想和你说的一模一样,所以我就用我自己的方式说了出来