Классы и массивы, как инициализировать? - PullRequest
0 голосов
/ 01 ноября 2011

Я работаю над некоторыми частичными уроками, но не могу понять, как это сделать. Это мои занятия:

Partial Public Class Form
    Private InfoField() As Info

    Private FormgroupField() As FormGroup

    Private tittle As String


    Public Property Info() As Info()
    Get
        Return Me. InfoField
    End Get
    Set
        Me. InfoField = value
    End Set
    End Property

Public Property FormGroup() As FormGroup()
    Get
        Return Me.GromGroupField
    End Get
    Set
        Me.FormGroupField = value
    End Set
    End Property

   Public Property tittle() As String
    Get
        Return Me.tittleField
    End Get
    Set
        Me.tittleField = value
    End Set
 End Property
End class



Partial Public Class Info
      Private ChangeFormField() As ChangeForm

    Private formYearField() As FormYea

    Private idField As String

    Public Property ChangeForm() As ChangeForm()
    Get
        Return Me.changeFormField
    End Get
    Set
        Me.changeFormField = value
    End Set
    End Property

   Public Property FormYear() As FormYear()
    Get
        Return Me.formYearField
    End Get
    Set
        Me.formYearField = value
    End Set
    End Property

   Public Property id() As String
    Get
        Return Me.idField
    End Get
    Set
        Me.idField = value
    End Set
    End Property    

  End Class

 Partial Public Class ChangeForm
Private idField As String

    Private valueField As String

<properties goes here>
End Class

Partial Public Class FormYear

    Private idField As String

    Private valueField As String

<properties goes here>
 End Class

А для класса FormGroup организация такая же.

Я хочу создать частичные классы для расширения этих классов, поэтому, когда я использую все эти классы в другом проекте, мне приходится иметь дело только с (самым верхним) классом (Form), а не с другими классами (такими как Info и FormGroup. Вот что я люблю делать:

Partial Public Class Form
 Public Sub Init()
    Me.Info = New Info
    Me.FormGroup = New FormGroup

    Me.Info.Init()
    Me.FormGroup.Init()
End Sub

End Class

Partial Public Class Info
 Public Sub Init()
    Me.FormYear = New FormYear
    Me.ChangeForm = New ChangeForm

    Me.changeForm.Init()
End Sub

Но я не могу написать

Me.Info = New Info
Me.FormGroup = New FormGroup

потому что это массивы с классами. Как я могу сделать это в моем классе Form and Info?

Заранее спасибо.

1 Ответ

1 голос
/ 01 ноября 2011

Сначала необходимо создать массив, затем выполнить цикл по массиву и назначить каждый элемент. Кроме того, если у вас нет веских причин, делайте это в конструкторе, а не в отдельном методе init.

Public Class Form
    Public Sub New()
        'In VB, you give the max index, not the length.
        'I prefer listing this as (whatever I want for length) - 1
        Me.Info = New Info(size - 1) {}
        For i = 0 to size - 1
            Me.Info(i) = New Info()
        Next
        'similarly for other fields
    End Sub
End Class

В качестве альтернативы, если вы обнаружите, что у вас много полей массива, и все они имеют конструкторы по умолчанию, вы можете создать класс FixedCollection, который будет инкапсулировать повторяющийся код инициализации.

Public Class FixedCollection(Of T As New)
    Inherits Collection(Of T)

    Public Sub New(ByVal size As Integer)
        MyBase.New(New T(size - 1) {})
        For i = 0 to size - 1
            Me.Items(i) = New T()
        Next
    End Sub

    'alternate constructors if you need additional initialization
    'beyond construction of each element
    Public Sub New(ByVal size As Integer, ByVal creator As Func(Of T))
        MyBase.New(New T(size - 1) {})
        If creator Is Nothing Then Throw New ArgumentNullException("creator")
        For i = 0 to size - 1
            Me.Items(i) = creator()
        Next
    End Sub
    'this overload allows you to include the index in the collection
    'if it would matter to creation
    Public Sub New(ByVal size As Integer, ByVal creator As Func(Of Integer, T))
        MyBase.New(New T(size - 1) {})
        If creator Is Nothing Then Throw New ArgumentNullException("creator")
        For i = 0 to size - 1
            Me.Items(i) = creator(i)
        Next
    End Sub

    'other collection overrides as needed here

End Class

EDIT: Добавлены перегрузки конструктора для случаев, когда конструктора элемента недостаточно.

Если вы используете конструкторы только с параметром создателя, вы можете удалить ограничение New для T.

Используйте следующие перегрузки:

Public Class Form
    Private InfoField As New FixedCollection(Of Info)(10,  
                Function()
                    Dim ret As New Info()
                    ret.Init()
                End Function)

End Class

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

...