静态/在VB.NET中共享和C#可见性

我面对VB.NET和C#(.NET2)中的情况,具有静态/共享成员的可见性。 在VB.NET中我觉得有点奇怪:

public class A { private static A instance; public static A Instance { get { return instance; } } public string Name { get { } } } 

用法A.Instance.Name // ONLY名称是“可见的”


VB.NET:

 Public Class A Private Shared _instance As A Public Shared ReadOnly Property Instance() As A Get Return _instance End Get End Property Public ReadOnly Property Name() As String Get Return "" End Get End Property End Class 

用法

 A.Instance.Instance.Instance.Instance... 

//共享成员的行为就像一个公共类,我可以重复它到无限…

这是微软的疏忽还是VB.NET的“function”?

这不是疏忽,但是你的VB代码触发警告,这显然意味着:不要使用这种表示法。

在VB中,静态成员可以通过实例访问,因为严格来说,VB 没有static :VB有关键字Shared ,这意味着成员在所有实例之间共享 ,而不是static成员不属于任何实例。

现在,这是这些关键字之间的语义区别。 碰巧这两个不同的语义倾向于具有完全相同的效果。

当然,C#中的static今天与VB.NET中的Shared相同,但它们的遗产不同,VB的Shared只有不同的历史,因此历史上有不同的含义。 有了这个含义,通过实例访问Shared成员是绝对有意义的。

当与Option Strict Off (松散键入)一起使用时,它也是有意义的:在这里,您有时不知道变量的类型,但您仍然可能想要访问Shared成员。 现在,您别无选择,只能使用实例来访问它:

 Option Strict Off ' … ' Dim o As Object = New A() ' Somewhere else, we want to access a static member of A but we don't know A: ' Dim instance = o.Instance 

这是一个特点; 这不是一个bug。 VB正在按设计工作。 关于静态方法是否可以被视为实例的方法,不同的语言做出了不同的选择。 VB允许它。 C ++允许它。 C#没有。

请记住,不同语言的设计标准是不同的,因此做出的决策是不同的。 在C#设计团队中,我们非常重视语言定义,这使得非法模式看起来很可疑; 因为将实例作为接收器传递给静态方法没有意义 (除非计算接收器表达式导致副作用),那么为什么允许用户键入无意义的代码呢?

在VB设计团队中,他们重视代码的工作方式,就像您第一次键入代码一样。 如果看起来有点狡猾,可能会发出警告,但允许它继续前进。

如果您对C#中静态调用设计中的一些更微妙的问题感兴趣,这是一个有趣的问题:

http://blogs.msdn.com/ericlippert/archive/2009/07/06/color-color.aspx

C#编译器不允许您在对象的实例上引用静态属性,仅允许在类型本身上引用静态属性。 这是C#而不是.NET CLR限制。 VB.NET将允许这个,但会警告它。