アプリ版:「スタンプのみでお礼する」機能のリリースについて

VB6でプログラムを作っていたときは
値のセットが配列になるとき
構造体を動的配列で宣言してデータを足して作りました。

VB2008で開発をすることになり
同じようなことをしたいのですが
もっと便利なやり方が登場したりするのでしょうか?
クラスで挑戦したのですが動的配列はできないようでした。

A 回答 (3件)

動的配列は若干扱いが変わっています。


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

この回答への補足

ありがとうございます。

動的配列はできそうな気がしてきました。
配列にしたいものが構造体の場合は
どうすればいいのか分かりません。

補足日時:2009/09/15 14:39
    • good
    • 0

構造体の場合でも配列の扱い方は一緒です。


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を取得する方法は
ないでしょうか?

補足日時:2009/09/15 18:01
    • good
    • 0

#書き連ねてたらやたら長くなってしまったので必要と思うところだけ抜粋して読んでくださいませ。



> できれば下記のようにしたかったので
> 同じようなことができないでしょうか?

■構造体+配列
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
    • good
    • 0
この回答へのお礼

ありがとうございます。
ゴールが見えてきました。
クラス+コレクションクラスでいってみます。

お礼日時:2009/09/16 10:27

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!