Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VB.NET和C#可见性中的静态/共享_C#_.net_Vb.net_Visual Studio_Accessor - Fatal编程技术网

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

VB.NET和C#可见性中的静态/共享,c#,.net,vb.net,visual-studio,accessor,C#,.net,Vb.net,Visual Studio,Accessor,我在VB.NET和C#(.NET2)中遇到了静态/共享成员可见性的情况。在VB.NET中,我觉得有点奇怪: public class A { private static A instance; public static A Instance { get { return instance; } } public string Name { get { } }

我在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
用法:

//共享成员的行为类似于类公共成员,我可以无限重复它。


这是Microsoft的疏忽还是VB.NET的“功能”?

这不是疏忽,但您的VB代码将触发一个警告,这显然意味着:不要使用此符号

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

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

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

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

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

C#编译器不允许在对象实例上引用静态属性,只允许在类型本身上引用。这是一个C#而不是.NET CLR限制。VB.NET将允许此操作,但会发出警告。

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

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

在VB设计团队中,他们重视代码的工作方式,就像您第一次键入代码时所希望的那样;如果某件事情看起来有点可疑,可能会发出警告,但允许它继续前进

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


如果这是真的,那么我将把它添加到我的“为什么是C而不是VB”;-)@AdamRalph:这将是不成熟和未经反思的。这是一个C#而不是.NET CLR限制。IMHO,这个限制很好,因为不要通过类名和类实例复制静态成员的可见性。此外,这还可以防止将诸如Instance.StaticMember.StaticMember.StaticMember.StaticMember.StaticMember…C#之类的字段调用“无限化”,这似乎比VB.NET更准确、更清晰,因为它应该考虑到它与VB家族的“历史”兼容性。无论如何,C#不允许通过类名和类实例在静态成员的可见性中重复。它还可以防止字段调用的“无限化”,如Instance.StaticMember.StaticMember。。。这可能会让类实例的用户感到尴尬。真的,因为我认为我的实例更静态,而不是共享的,所以我不希望在singleton实例中还有一个实例,所以。。。
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