Практическое руководство. Преобразование пользовательской коллекции в коллекцию со строгим типом Visual Basic
Обновлен: Ноябрь 2007
В Visual Basic 6.0 содержимое пользовательской коллекции ограничивается одним определенным классом. Такая коллекция также называется коллекцией со строгим типом. В Visual Basic 2008 имеется несколько вариантов создания типизированных классов из пользовательских коллекций Visual Basic 6.0. В данном разделе рассматриваются три процедуры, каждой из которых соответствует определенный параметр.
В данном разделе предполагается, что была создана пользовательская коллекция Visual Basic 6.0 с помощью Программы построения классов. Такая коллекция имеет следующие члены:
Add (добавляет в коллекцию новый экземпляр пользовательского класса);
Item (возвращает экземпляр из коллекции в соответствии с индексом);
Count (возвращает число экземпляров в коллекции);
Remove (удаляет из коллекции экземпляр в соответствии с индексом);
Enumeration (поддерживает перечисление с помощью синтаксиса For Each).
Использование мастера обновления для создания коллекции
Откройте проект Visual Basic 6.0 в Visual Basic 2008. Для класса коллекции с именем Forest, содержащего экземпляры класса Tree, обновленный код показан ниже. Преимуществом данного метода является отсутствие необходимости в изменении кода.
' For this example, the Tree class has no members. Option Strict Off Option Explicit On Friend Class Tree End Class Friend Class Forest Implements System.Collections.IEnumerable 'local variable to hold collection Private mCol As Collection Public Function Add(Optional ByRef sKey As String = "") As Tree 'create a new object Dim objNewMember As Tree objNewMember = New Tree 'set the properties passed into the method If Len(sKey) = 0 Then mCol.Add(objNewMember) Else mCol.Add(objNewMember, sKey) End If 'return the object created Add = objNewMember 'UPGRADE_NOTE: Object objNewMember may not be destroyed until it is garbage collected. Click for more: 'ms-help://MS.MSDNQTR.80.en/commoner/redir/redirect.htm?keyword="vbup1029"' objNewMember = Nothing End Function Default Public ReadOnly Property Item(ByVal vntIndexKey _ As Object) As Tree Get 'used when referencing an element in the collection 'vntIndexKey contains either the Index or Key to the collection, 'this is why it is declared as a Variant 'Syntax: Set foo = x.Item(xyz) or Set foo = x.Item(5) Item = mCol.Item(vntIndexKey) End Get End Property Public ReadOnly Property Count() As Integer Get 'used when retrieving the number of elements in the 'collection. Syntax: Debug.Print x.Count Count = mCol.Count() End Get End Property 'UPGRADE_NOTE: NewEnum property was commented out. Click for more: 'ms-help://MS.MSDNQTR.80.en/commoner/redir/redirect.htm?keyword="vbup1054"' 'Public ReadOnly Property NewEnum() As stdole.IUnknown 'Get 'this property allows you to enumerate 'this collection with the For...Each syntax 'NewEnum = mCol._NewEnum 'End Get 'End Property Public Function GetEnumerator() As System.Collections.IEnumerator _ Implements System.Collections.IEnumerable.GetEnumerator 'UPGRADE_TODO: Uncomment and change the following line to return the collection enumerator. Click for more: 'ms-help://MS.MSDNQTR.80.en/commoner/redir/redirect.htm?keyword="vbup1055"' 'GetEnumerator = mCol.GetEnumerator End Function Public Sub Remove(ByRef vntIndexKey As Object) 'used when removing an element from the collection 'vntIndexKey contains either the Index or Key, which is why 'it is declared as a Variant 'Syntax: x.Remove(xyz) mCol.Remove(vntIndexKey) End Sub 'UPGRADE_NOTE: Class_Initialize was upgraded to Class_Initialize_Renamed. Click for more: 'ms-help://MS.MSDNQTR.80.en/commoner/redir/redirect.htm?keyword="vbup1061"' Private Sub Class_Initialize_Renamed() 'creates the collection when this class is created mCol = New Collection End Sub Public Sub New() MyBase.New() Class_Initialize_Renamed() End Sub 'UPGRADE_NOTE: Class_Terminate was upgraded to Class_Terminate_Renamed. Click for more: 'ms-help://MS.MSDNQTR.80.en/commoner/redir/redirect.htm?keyword="vbup1061"' Private Sub Class_Terminate_Renamed() 'destroys collection when this class is terminated 'UPGRADE_NOTE: Object mCol may not be destroyed until it is garbage collected. Click for more: 'ms-help://MS.MSDNQTR.80.en/commoner/redir/redirect.htm?keyword="vbup1029"' mCol = Nothing End Sub Protected Overrides Sub Finalize() Class_Terminate_Renamed() MyBase.Finalize() End Sub End Class
В .NET Framework и Visual Basic 2008 имеется несколько универсальных коллекций. Преимуществом использования универсальных классов является весьма небольшой объем кода, необходимого для реализации класса.
Создание коллекции с помощью универсальных коллекций
Создайте определение класса. Ниже приведен пример класса Tree:
Public Class Tree Public Species As String End Class
Создайте универсальный класс списка из .NET Framework. Это объявление по существу полностью заменяет класс Forest в процедуре, приведенной выше под названием "Использование мастера обновления для создания коллекции".
Dim forest As New System.Collections.Generic.List(Of Tree)
Напишите код для обращения к списочному объекту. В следующем примере кода производится добавление пяти экземпляров класса Tree в коллекцию и их печать:
For count As Integer = 1 To 5 Dim sapling As New Tree sapling.Species = "oak" Forest.Add(sapling) Next For Each sapling As Tree In Forest MsgBox(sapling.Species) Next
В .NET Framework включен класс CollectionBase. Коллекции со строгим типом создаются путем наследования от класса CollectionBase. При использовании данного метода требуется меньше кода, чем при использовании мастера обновления, но больше, чем при применении универсальных коллекций. Он более гибок по сравнению с использованием универсальных коллекций, так как программист может добавлять в класс коллекции дополнительные члены.
Создание коллекции на основе класса CollectionBase
Создайте определение класса. Ниже приведен пример класса Tree:
Public Class Tree Public Species As String End Class
Создайте класс, наследуемый от класса CollectionBase. Добавьте по меньшей мере метод Add и свойство Item. Благодаря этому класс станет строго типизированным.
Class TreeCollection Inherits System.Collections.CollectionBase Public Sub Add(ByVal value As Tree) Me.List.Add(value) End Sub Default Public Property Item(ByVal index As Integer) As Tree Get Return CType(Me.List(index), Tree) End Get Set(ByVal value As Tree) If index <= Me.Count - 1 Then Me.List(index) = value Else Throw New IndexOutOfRangeException() End If End Set End Property End Class
Напишите код для обращения к списочному объекту. В следующем примере кода производится добавление пяти экземпляров класса Tree в коллекцию и их печать:
Dim forest As New TreeCollection
For count As Integer = 1 To 5 Dim sapling As New Tree sapling.Species = "oak" Forest.Add(sapling) Next For Each sapling As Tree In Forest MsgBox(sapling.Species) Next