我遇到过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
// 仅限姓名“可见”
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“功能”?
答案 0 :(得分:20)
这不是疏忽,但你的VB代码会触发警告,这显然意味着:不要使用这种表示法。
在VB中,静态成员可以通过实例访问,因为严格来说,VB 没有static
:VB有关键字{{ 1}},意味着成员在所有实例之间共享,而不是Shared
,其中成员不属于任何实例。
现在,这是这些关键字之间的语义区别。事实恰恰相反,这两种截然不同的语义往往具有完全相同的效果。
当然,今天C#中的static
与VB.NET中的static
相同,但它们的遗产不同,而VB Shared
只有不同的历史,因此历史上有不同的含义。使用 this 意义,通过实例访问Shared
成员是绝对有意义的。
与Shared
一起使用时也很有意义(松散打字):在这里,你有时不知道变量的类型,但你仍然可能想要访问{{1成员。现在,您别无选择,只能使用实例来访问它:
Option Strict Off
答案 1 :(得分:10)
这是一个特色;这不是一个错误。 VB正在按设计工作。关于静态方法是否可以被视为实例的方法,不同的语言做出了不同的选择。 VB允许它。 C ++允许它。 C#没有。
请记住,不同语言的设计标准是不同的,因此做出的决策是不同的。在C#设计团队中,我们非常重视语言定义,这使得非法模式看起来很可疑;因为将实例作为接收器传递给静态方法没有含义(除非计算接收器表达式会产生副作用),那么为什么允许用户键入无意义的代码?
在VB设计团队中,他们重视代码的工作,就像你第一次输入代码一样工作;如果看起来有点狡猾,可能会发出警告,但允许它继续前进。
如果您对C#中静态调用设计中一些更微妙的问题感兴趣,这是一个有趣的问题:
http://blogs.msdn.com/ericlippert/archive/2009/07/06/color-color.aspx
答案 2 :(得分:0)
C#编译器不允许您在对象的实例上引用静态属性,仅在类型本身上引用。这是C#而不是.NET CLR限制。 VB.NET将允许这个,但会警告它。