- ベストアンサー
VB6でやると構造体の配列になる変数をVB2008では何で作ればいいか
VB6でプログラムを作っていたときは 値のセットが配列になるとき 構造体を動的配列で宣言してデータを足して作りました。 VB2008で開発をすることになり 同じようなことをしたいのですが もっと便利なやり方が登場したりするのでしょうか? クラスで挑戦したのですが動的配列はできないようでした。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
#書き連ねてたらやたら長くなってしまったので必要と思うところだけ抜粋して読んでくださいませ。 > できれば下記のようにしたかったので > 同じようなことができないでしょうか? ■構造体+配列 Public Structure MainGroup Public ID As Integer Public SubGroups As SubGroup() End Structure Public Structure SubGroup Public ID As Integer Public Value1 As Integer Public Value2 As Integer Public Sub New(ByVal ID As Integer, ByVal Value1 As Integer, ByVal Value2 As Integer) Me.ID = ID : Me.Value1 = Value1 : Me.Value2 = Value2 End Sub End Structure Public Class Program Public Shared Sub Main() Dim DataArray As MainGroup() = {} Array.Resize(DataArray, 3) With DataArray(0) .ID = 1 Array.Resize(.SubGroups, 4) .SubGroups(0) = New SubGroup(101, 123, 456) .SubGroups(1) = New SubGroup(102, 234, 567) ' (略) End With With DataArray(1) ' (略) End With End Sub End Class ■クラス+コレクション Public Class MainGroup Public ID As Integer Public SubGroup As New System.Collections.Generic.List(Of SubGroup) End Class Public Class SubGroup Public ID As Integer Public Value1 As Integer Public Value2 As Integer Public Sub New(ByVal ID As Integer, ByVal Value1 As Integer, ByVal Value2 As Integer) Me.ID = ID : Me.Value1 = Value1 : Me.Value2 = Value2 End Sub End Class Public Class Program Public Shared Sub Main() Dim DataList As New System.Collections.Generic.List(Of MainGroup) Dim NewMain As MainGroup NewMain = New MainGroup NewMain.ID = 1 NewMain.SubGroup.Add(New SubGroup(101, 123, 456)) NewMain.SubGroup.Add(New SubGroup(102, 234, 567)) ' (略) DataList.Add(NewMain) End Sub End Class 配列+クラスはNULL参照を発生させる可能性がある点で相性がよくありません。コレクション+構造体は、#2で挙げたようにデータ書き換えの手間がかかり、やはり相性はよくありません。 配列は要素数の変動に対してパフォーマンスが悪く、細かく増減させるには不向きです。コレクションは増減することを前提としている点や、削除した箇所を詰めたり途中に挿入したりが容易な点で優れています。 クラス or 構造体、配列 or コレクション をどう組み合わせるかはこれらのほか、ユーザビリティ・保守性・整合性・パフォーマンスなどと共に天秤にかけることになるでしょう。状況にあわせてうまく使い分けてください。 > addでどんどん追加して全体をループさせずに小項目IDを取得する方法 小項目IDがユニークであれば、リストコレクションではなく辞書コレクションを使うことでIDからクラスを取得できるようになります。クラスが保持しているデータをキーに使う場合は、コレクションを継承したクラスを作り、AddをShadowsで置き換えたほうがコーディングミスを防ぐことが出来ます。 ■クラス+コレクションクラス Public Class Group Public MainID As Integer Public SubID As Integer Public Value1 As Integer Public Value2 As Integer End Class Public Class GroupCollection : Inherits System.Collections.Generic.Dictionary(Of Integer, Group) Public Shadows Sub Add(ByVal Item As Group) MyBase.Add(Item.SubID, Item) End Sub End Class Public Class Program Public Shared Sub Main() Dim DataDict As New GroupCollection Dim NewGroup As New Group NewGroup.MainID = 1 NewGroup.SubID = 101 NewGroup.Value1 = 123 NewGroup.Value2 = 234 DataDict.Add(NewGroup) Console.WriteLine(DataDict.Item(101).Value2) ' 出力 234 End Sub End Class
その他の回答 (2)
- うぃず(@Wizard_Zero)
- ベストアンサー率69% (344/495)
構造体の場合でも配列の扱い方は一緒です。 Public Class Hoge を Public Structure Hoge に変えればOKです。 ※コレクションで構造体を扱う際の注意点 コレクションにおいてはクラス(参照型)と構造体(値型)でメンバーの書き換え方が異なります。 Dim HogeList As New System.Collections.Generic.List(Of Hoge) HogeList.Add(New Hoge()) HogeList.Item(0).Prop = xxx ' ←ここ Hogeがクラスであればこれで問題なく動作しますが、構造体の場合はこのような代入はできません。 Dim hogeItem As Hoge = HogeList.Item(0) hogeItem.Prop = xxx HogeList.Item(0) = hogeItem このように、一度構造体ごと取出し、構造体ごとコレクションに戻す必要があります。
補足
ありがとうございます。 コレクションでクラスを使っていけそうな気がしてきました。 できれば下記のようにしたかったので 同じようなことができないでしょうか? 配列1() as 大項目構造体 大項目構造体 大項目ID 小項目() 小項目構造体 小項目ID 小項目値1 小項目値2 こうすると大項目ごとにDBの検索テーブルが違うときに 小項目IDを条件に含めることが楽だと思っていました。 クラスを 大項目ID 小項目ID 小項目値1 小項目値2 で定義しました。 addでどんどん追加して全体をループさせずに小項目IDを取得する方法は ないでしょうか?
- うぃず(@Wizard_Zero)
- ベストアンサー率69% (344/495)
動的配列は若干扱いが変わっています。 ReDimでも配列数の変更はできますが、私はArray.Resizeを使うようにしています。 要素数がちょくちょく変わるのであれば、コレクションを使うほうがスマートかもしれません。暗黙の型変換を回避するために、ジェネリックを使うことをお勧めします。 Public Class Hoge End Class Public Class Program Public Shared Sub Main() Dim HogeArray As Hoge() = {} Array.Resize(HogeArray, 3) ' 要素数を変更 HogeArray(0) = New Hoge() HogeArray(1) = New Hoge() HogeArray(2) = New Hoge() 'HogeArray(3) = New Hoge() ' これはエラーになる Array.Resize(HogeArray, 4) ' 配列数を変えても既存のデータは残る 'ReDim Preserve clsHoge(3) ' VB6.0の書き方でも可 HogeArray(3) = New Hoge() ' Array.Resizeでは要素数、ReDimではインデックスの最大値 ' 配列の大きさを指定する値が異なるので注意 ' リストコレクションを使えば配列数を気にしなくてよい Dim HogeList As New System.Collections.Generic.List(Of Hoge) HogeList.Add(New Hoge()) HogeList.Add(New Hoge()) HogeList.Add(New Hoge()) HogeList.Add(New Hoge()) For Each Item As Hoge In HogeList ' コレクションの一覧を列挙 Next End Sub End Class
補足
ありがとうございます。 動的配列はできそうな気がしてきました。 配列にしたいものが構造体の場合は どうすればいいのか分かりません。
お礼
ありがとうございます。 ゴールが見えてきました。 クラス+コレクションクラスでいってみます。