Vb.net 在另一个类中声明一个类的目的是什么?

Vb.net 在另一个类中声明一个类的目的是什么?,vb.net,class,encapsulation,Vb.net,Class,Encapsulation,我来自VBA世界,在那里,将代码分解为类、名称空间和模块的选项是有限的。现在我来到了一个有很多选择的世界,我感到迷失了 我想知道在另一个类中声明一个类的目的是什么?(见下面的示例) 如果我创建一个新的FirstClass(比如myFirstClass)实例,SecondClass不会被实例化。 更奇怪的是(至少对我来说),intelissense为我提供了myFirstClass.SecondClass。显然,由于该类没有实例化,我无法访问它的任何成员 那么,只有当SecondClass包含s

我来自VBA世界,在那里,将代码分解为类、名称空间和模块的选项是有限的。现在我来到了一个有很多选择的世界,我感到迷失了

我想知道在另一个类中声明一个类的目的是什么?(见下面的示例)

如果我创建一个新的
FirstClass
(比如
myFirstClass
)实例,
SecondClass
不会被实例化。 更奇怪的是(至少对我来说),intelissense为我提供了
myFirstClass.SecondClass
。显然,由于该类没有实例化,我无法访问它的任何成员


那么,只有当
SecondClass
包含
shared
成员时,这才有用吗? 为了尝试回答这个问题,我在
SecondClass
中添加了一个共享成员:

Class FirstClass
    Public OnePropertyInside As String
    Class SecondClass
        Public AnotherProperty As String
        Public Shared SharedProperty As String
    End Class
End Class
我运行了一些测试,这些测试带来了次要问题(参见代码中的注释)


通常这样做是因为要限制嵌套类的范围

因此,如果您只需要在“父”类中使用这个类(就范围而言),那么将它定义为嵌套类通常是一个好主意


如果您可能需要在其程序集之外使用该类,那么最好将其定义为一个完全独立的类(在其自己的文件中),然后相应地定义您的关系。您需要在另一个类中实例化一个类(无论它是独立的还是嵌套的,这都是相同的,因此它的位置与该点基本无关)。

您可以将其视为最内部的类是某种帮助器类。甚至可能根本不需要使用它。将内部类(或简单的嵌套类)嵌套在外部类中可以访问外部类的所有成员。您甚至可以访问初始外部类中的私有成员


编辑:为了澄清,我的意思是内部可以访问外部的私有成员,而不是相反

当您这样做时,内部类可以被其他类访问(它的可访问性是
Public
Friend
),外部类基本上就像一个名称空间。例如,使用您的示例,您可以创建嵌套类的新对象,而无需创建外部类:

Dim x As New FirstClass.SecondClass()

最明显的好处是代码的结构化组织,很像名称空间和代码文件。因此,举例来说,为帮助更好地组织常量,对常量使用嵌套类并不少见:

Public Class Urls
    Public Class Processing
        Public Const Submit As String = "..."
        Public Const Cancel As String = "..."
    End Class

    Public Class Reporting
        Public Const Daily As String = "..."
        Public Const Weekly As String = "..."
    End Class
End Class

' ...

Dim url As String = Urls.Reporting.Daily
然而,除了像这样的东西很有用的一组狭窄的情况之外,大多数人更愿意根本不嵌套公共类

然而,正如其他人所提到的,您真正能够看到嵌套类被相当经常地使用的地方是
Private
类。如果您需要一个小的helper类,而该类将无法在您的类之外编写代码,那么没有理由公开它。即使您将它的可访问性设置为
Friend
,它仍然对同一项目中的所有其他类可见。因此,如果您真的想对其他所有内容隐藏它,那么您将希望使它成为一个嵌套的私有类。例如:

Public Class MyClass
    Public Function GetTheIdOfSomething() As Integer
        Dim d As Details = GetDetailsAboutSomething()
        If d.Value Is Nothing Then
            Return d.Id
        Else
            Throw New Exception()
        End If
    End Sub

    Private Function GetDetailsAboutSomething() As Details
        ' ... return a Details object
    End Function

    Private Class Details
        Public Property Id As Integer
        Public Property Value As String
    End Class
End Class

那不是真的。外部类无法访问嵌套类的私有成员。@Stevendogart我的回答可能是用这样一种方式写的,让人感到困惑,我已经进行了相应的编辑,其目的是传达内部可以访问外部的私有方法。我感到困惑。所以这只是一种预期的行为,对吗?“mother”类声明私有成员,只能从th类块中访问这些成员。由于嵌套类是“母亲”类块的一部分,因此它可以访问上述私有成员?@Ama是的,没错!“最明显的好处是代码的结构化组织,很像名称空间和代码文件。”有趣。。在
块中嵌套类比在
命名空间
块中嵌套类有什么好处?@Ama其实没有太大区别,只是大多数人只导入命名空间(即使你也可以导入类)。因此,通过将其放入嵌套类中,您可能希望看到在使用它的任何地方都会写出完整的嵌套链,而对于命名空间,导入命名空间比完全限定命名空间更常见。我明白了,所以我想如果该类及其嵌套类是紧密相关的,那么我应该嵌套类,但是如果没有,那么我应该将before嵌套类包含到namesepce块中,这样,如果用户希望以这种方式编码,他们就可以导入名称空间。是的。听起来你走对了方向。正如其他人所暗示的,私有类的嵌套是相对常见的。公共类的嵌套是奇怪的,通常是避免的,但如果您需要它,它仍然可以作为一个选项使用……而且很少有情况下您会高兴地发现您可以这样做。
Public Class Urls
    Public Class Processing
        Public Const Submit As String = "..."
        Public Const Cancel As String = "..."
    End Class

    Public Class Reporting
        Public Const Daily As String = "..."
        Public Const Weekly As String = "..."
    End Class
End Class

' ...

Dim url As String = Urls.Reporting.Daily
Public Class MyClass
    Public Function GetTheIdOfSomething() As Integer
        Dim d As Details = GetDetailsAboutSomething()
        If d.Value Is Nothing Then
            Return d.Id
        Else
            Throw New Exception()
        End If
    End Sub

    Private Function GetDetailsAboutSomething() As Details
        ' ... return a Details object
    End Function

    Private Class Details
        Public Property Id As Integer
        Public Property Value As String
    End Class
End Class