Какова цель объявления класса в другом классе? - PullRequest
0 голосов
/ 07 февраля 2019

Я из мира VBA, где возможности разбивать ваш код на классы, пространства имен и модули ограничены.Сейчас я попал в мир, где вариантов много, и я чувствую себя потерянным.

Я хотел бы знать, какова цель объявления Класса в другом Классе?(см. пример ниже)

Class FirstClass
    Public OnePropertyInside As String
    Class SecondClass
        Public AnotherProperty As String
    End Class
End Class

Если я создаю новый экземпляр 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

Я провел несколько тестов, которые принесли дополнительные вопросы (см. Комментарии в коде)

Sub Main()       

    Dim myFirstClass As New FirstClass
    'Works as expected
    Console.WriteLine(myFirstClass.OneProperty)

    'What is the difference between the two lines below?
    Console.WriteLine(myFirstClass.SecondClass.SharedProperty)
    Console.WriteLine(FirstClass.SecondClass.SharedProperty)

    'This line cannot be compiled, this demonstrates SecondClass is not instantiated when FirstClass is.
    Console.WriteLine(myFirstClass.SecondClass.AnotherProperty)

    Dim mySecondClass As New FirstClass.SecondClass
    'Works as expected, but I feel this hierarchy should better be dealt with through a namespace statement?
    Console.WriteLine(mySecondClass.AnotherProperty)

End Sub

Ответы [ 3 ]

0 голосов
/ 07 февраля 2019

Вы можете думать об этом, как будто самый внутренний класс является своего рода вспомогательным классом.Это, возможно, даже не должно использоваться вообще.Вложив внутренний класс (или просто вложенный класс) во внешний класс, вы получаете доступ ко всем членам внешнего.Вы даже можете получить доступ к закрытым членам внутри этого начального внешнего класса.

Редактировать: Для пояснения я хочу сказать, что внутренний может получить доступ к закрытым членам внешнего, а не наоборот.

0 голосов
/ 07 февраля 2019

Когда вы делаете это, и внутренний класс становится доступным для других классов (его доступность 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.Если вам нужен небольшой вспомогательный класс, который бесполезен для написания кода вне вашего класса, нет никаких причин выставлять его.Даже если вы установите его доступность 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
0 голосов
/ 07 февраля 2019

Обычно вы делаете это, потому что хотите ограничить область действия вложенного класса.

Итак, если вам нужно использовать этот класс только из «родительского» класса (с точки зрения области видимости), то, как правило, рекомендуется определить его как вложенный класс.

Если вам может понадобиться использовать класс вне его сборки, то лучше определить его как совершенно отдельный класс (в своем собственном файле), а затем определить ваши отношения соответствующим образом.Вам нужно будет создать один экземпляр внутри другого (это одно и то же, независимо от того, является ли он отдельным или вложенным - поэтому его расположение в значительной степени не имеет значения для этой точки).

...