.net 为什么允许引用Windows窗体的非共享成员?

.net 为什么允许引用Windows窗体的非共享成员?,.net,vb.net,.net,Vb.net,我们在代码中确定问题时遇到了这个问题。我们已经修复了错误,但问题仍然存在: 为什么允许引用“Windows窗体”的非共享成员 为了复制行为,请创建新的Windows窗体应用程序(我使用的是VS2012、.net4.0),使用以下内容填充默认窗体Form1.vb: Option Strict On Option Explicit On Public Class Form1 Private _private As String Public ReadOnly Property

我们在代码中确定问题时遇到了这个问题。我们已经修复了错误,但问题仍然存在:

为什么允许引用“Windows窗体”的非共享成员

为了复制行为,请创建新的Windows窗体应用程序(我使用的是VS2012、.net4.0),使用以下内容填充默认窗体Form1.vb:

Option Strict On
Option Explicit On

Public Class Form1

    Private _private As String

    Public ReadOnly Property NotSharedProperty As String
        Get
            Return _private
        End Get
    End Property

End Class
然后添加一个新类并将其命名为PropertClass,并用以下内容填充:

Option Strict On
Option Explicit On

Public Class ProperClass

    Private _private As String

    Public ReadOnly Property NotSharedProperty As String
        Get
            Return _private
        End Get
    End Property

End Class
然后添加另一个类,称之为ExampleClass并填充它:

Option Strict On
Option Explicit On

Public Class ExampleClass

    Public Sub New()

        If Form1.NotSharedProperty Is Nothing Then
            '.....................
        End If

        If ProperClass.NotSharedProperty Is Nothing Then
            '.....................
        End If


    End Sub

End Class

在ExampleClass中,
ProperClass.NotSharedProperty
给了我“对非共享成员的引用需要对象引用。”正如人们所期望的那样<代码>表单1。NotSharedProperty没有。为什么?

这是许多Visual Basic.NET兼容性功能之一

在旧式VisualBasic中按类型引用表单时,将获得对该表单默认实例的引用。这就是过去VB开发的方式(VB并不是唯一使用这种约定的环境)。大多数时候,每个表单实际上只有一个实例


由于您并非有意利用此功能,因此可能从未实际使用过默认实例,而是根据需要创建自己的实例。在这种情况下,
Form1.NotSharedProperty
将只返回默认值。

这是Visual Basic.NET众多兼容性功能之一

在旧式VisualBasic中按类型引用表单时,将获得对该表单默认实例的引用。这就是过去VB开发的方式(VB并不是唯一使用这种约定的环境)。大多数时候,每个表单实际上只有一个实例


由于您并非有意利用此功能,因此可能从未实际使用过默认实例,而是根据需要创建自己的实例。那么,,
Form1.NotSharedProperty
只返回默认值。

Form1.NotSharedProperty
使用VB在您不执行表单实例时创建的默认表单实例
Form1.NotSharedProperty
使用VB在您不执行表单实例时创建的默认表单实例需要指出的是,大多数有经验的VB.NET开发人员都不赞成使用默认实例。它们往往会引入许多难以诊断的错误。你应该避免它们。在我们的案例中,很难确定错误。问题很简单,我们没有花太多心思就尝试访问属性,因为它是一个共享属性,而不是获取实例化表单对象的属性,这正是我们的意思。IDE并没有抱怨,所以并没有发现这个bug导致一些相当奇怪的行为。接受答案。@parvee是的,你不能关闭这个功能有点烦人。据我所知,在VB.NET中“禁用”默认实例的唯一方法是删除无参数构造函数(通常,您会添加一个静态“构造函数”方法,同时保持构造函数本身私有或受保护)。实际上,我很少故意这样做,因为我通常显式地传递依赖项,所以我不倾向于使用具有公共无参数构造函数的表单。我认为必须指出,大多数有经验的VB.NET开发人员确实不赞成使用默认实例。它们往往会引入许多难以诊断的错误。你应该避免它们。在我们的案例中,很难确定错误。问题很简单,我们没有花太多心思就尝试访问属性,因为它是一个共享属性,而不是获取实例化表单对象的属性,这正是我们的意思。IDE并没有抱怨,所以并没有发现这个bug导致一些相当奇怪的行为。接受答案。@parvee是的,你不能关闭这个功能有点烦人。据我所知,在VB.NET中“禁用”默认实例的唯一方法是删除无参数构造函数(通常,您会添加一个静态“构造函数”方法,同时保持构造函数本身私有或受保护)。在实践中,我很少故意这样做,因为我通常显式地传递依赖项,所以我不倾向于使用具有公共无参数构造函数的表单。