方法 : カスタム コレクションを Visual Basic の型指定されたコレクションに変換する
更新 : 2007 年 11 月
Visual Basic 6.0 のカスタム コレクションでは、コレクションのコンテンツは特定の 1 つのクラスに制限されます。これは、型指定されたコレクションとも呼ばれます。Visual Basic 2008 では、いくつかの方法で Visual Basic 6.0 のカスタム コレクションから型指定されたクラスを作成できます。ここでは、3 つのプロシージャを示してそれぞれの方法を説明します。
説明では、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 クラスの 5 つのインスタンスをコレクションに追加し、それらを出力します。
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 クラスの 5 つのインスタンスをコレクションに追加し、それらを出力します。
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