tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトル配列とクラス
記事No5325
投稿日: 2007/04/12(Thu) 13:22
投稿者ひでと
お世話になります。配列に自分で独自のクラスを入れて使用する方法がわかりません。

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim a() As クロス材 = New クロス材() {}
        a(0).板厚 = 2.3
        a(1).板厚 = 3.2
    End Sub
End Class
として 「クロス材」の配列を作ろうとしているのですが、
'System.IndexOutOfRangeException' の初回例外が WindowsApplication1.exe で発生しました。となります。どのように直したらよいのでしょうか?
 

Public Class クロス材
    Private new板厚 As New Double
     Public Property 板厚() As Double
        Get
            Return new板厚
        End Get
        Set(ByVal value As Double)
            new板厚 = value
        End Set
    End Property
End Class

[ツリー表示へ]
タイトルRe: 配列とクラス
記事No5327
投稿日: 2007/04/12(Thu) 14:17
投稿者Hongliang
配列は本棚です。
New で本棚を作っても、棚の中身である本は自動的には入りません。
本も本棚同様に作る(New する)なりして用意する必要があります。

更に、
> Dim a() As クロス材 = New クロス材() {}
この宣言では、「この 0 冊の本が入る本棚を作れ」という意味になります。
// { } の中に指定した分だけの本が入る本棚を用意します。ついでに { } の中の本を本棚に入れ
てくれます。
元々 0 冊しか入らない本棚にはどう頑張っても一冊も入りません。配列は固定長ですので、後から
増やすことは基本的にできません。
この辺についてはヘルプで配列を調べてください。

[ツリー表示へ]
タイトルRe^2: 配列とクラス
記事No5328
投稿日: 2007/04/12(Thu) 14:50
投稿者ひでと
ありがとうございました。VB6との混乱を起こしていました。
VS2005では ReDimを使う必要が無いように勘違いしていました。
さらに配列変数の構文も微妙に違うのですね。


> 配列は本棚です。
> New で本棚を作っても、棚の中身である本は自動的には入りません。
> 本も本棚同様に作る(New する)なりして用意する必要があります。
>
> 更に、
> > Dim a() As クロス材 = New クロス材() {}
> この宣言では、「この 0 冊の本が入る本棚を作れ」という意味になります。
> // { } の中に指定した分だけの本が入る本棚を用意します。ついでに { } の中の本を本棚に入れ
> てくれます。
> 元々 0 冊しか入らない本棚にはどう頑張っても一冊も入りません。配列は固定長ですので、後から
> 増やすことは基本的にできません。
> この辺についてはヘルプで配列を調べてください。

    Public Sub test()
        Dim a() As トレイ.クロス材 = New トレイ.クロス材() {}
        Dim b As トレイ.クロス材
        b = New トレイ.クロス材 : b.板厚 = 2.3
        ReDim a(0) : a(0) = b
    End Sub
で良いのですよね?
もっとスマートに記載する方法があったら教えてください。

[ツリー表示へ]
タイトルRe^3: 配列とクラス
記事No5332
投稿日: 2007/04/12(Thu) 16:15
投稿者魔界の仮面弁士
個人的には配列ではなく、System.Collections.Generic 配下の
コレクション クラスで管理した方が便利だと思いますよ。


> Dim a() As トレイ.クロス材 = New トレイ.クロス材() {}
> ReDim a(0)
> a(0) = b

では、別の書き方をば。

=== 修正案 1 ===
Dim a() As トレイ.クロス材
ReDim a(0)
a(0) = b

=== 修正案 2 ===
Dim a As トレイ.クロス材()
ReDim a(0)
a(0) = b

=== 修正案 3 ===
Dim a(0) As トレイ.クロス材
a(0) = b

=== 修正案 4 ===
Dim a() As トレイ.クロス材 = New トレイ.クロス材(0) {b}

=== 修正案 5 ===
Dim a() As トレイ.クロス材 = New トレイ.クロス材() {b}

=== 修正案 6 ===
Dim a As トレイ.クロス材() = New トレイ.クロス材(0) {b}

=== 修正案 7 ===
Dim a As トレイ.クロス材() = New トレイ.クロス材() {b}

=== 修正案 8 ===
Dim a() As トレイ.クロス材 = {b}

=== 修正案 9 ===
Dim a As トレイ.クロス材() = {b}

[ツリー表示へ]
タイトルRe^4: 配列とクラス
記事No5335
投稿日: 2007/04/12(Thu) 17:44
投稿者ひでと
重ね重ね、ありがとうございます。
> 個人的には配列ではなく、System.Collections.Generic 配下の
> コレクション クラスで管理した方が便利だと思いますよ。
試してみました。こんな感じで良いのでしょうか?

    Private Sub Test()
        Dim a As New List(Of クロス材)
        Dim b As クロス材
        b = New クロス材 : a.Add(b)
        b = New クロス材 : a.Add(b)
        a(0).板厚 = 2.3
        a(1).板厚 = 3.2
        Dim c As New ラダートレイ
        c.クロス材 = a
    End Sub

   Public Class ラダートレイ
        Private newクロス材 As New List(Of クロス材)
        Public Property クロス材() As List(Of クロス材)
            Get
                Return newクロス材
            End Get
            Set(ByVal value As List(Of クロス材))
                newクロス材 = value
            End Set
        End Property
    End Class

VB6でもCollectionsがありましたが、使いこなせていませんでした。
おかしなところがありましたら、ご指摘ください。

PS.
配列変数も以下にテストしてみました。(修正案 2を使わせてもらったつもり)
    Public Sub test()
        Dim a() As クロス材
        Dim b As クロス材
        ReDim a(1)
        b = New クロス材 : a(0) = b
        b = New クロス材 : a(1) = b
        a(0).板厚 = 2.3
        a(1).板厚 = 3.2
        Dim c As New ラダートレイ
        c.クロス材 = a
    End Sub
> コレクション クラスで管理した方が便利だと思いますよ
このあたりの事、もう少し勉強させていただきます。

[ツリー表示へ]
タイトルRe^5: 配列とクラス
記事No5336
投稿日: 2007/04/12(Thu) 18:44
投稿者魔界の仮面弁士
メンバが[板厚]だけであれば、それをコンストラクタで受け取れる様にして、

  Dim clothList As New List(Of クロス材)

  clothList.Add( New クロス材(2.3) )
  clothList.Add( New クロス材(3.2) )

  Dim ladderTray As New ラダートレイ()
  ladderTray.クロス材 = clothList

のようにするのも手かも。


> Set(ByVal value As List(Of クロス材))
>   newクロス材 = value
> End Set
この場合、外部から「Nothing」がセットされる可能性もありますので、
何らかの対処が必要になるかも知れません。


(案1) Nothing の時は、空のリストを返すようにする。

  Get
    If newクロス材 Is Nothing Then
      Return New List(Of クロス材)
    Else
      Return newクロス材
    End If
  End Get


(案2) Nothing が渡された時は、自動的に空のリストをセットする。

  Set(ByVal value As List(Of クロス材))
    If value Is Nothing Then
      newクロス材 = New List(Of クロス材)
    Else
      newクロス材 = value
    End If
  End Set


(案3) そもそも、Nothing 代入を拒否する。

  Set(ByVal value As List(Of クロス材))
    If value Is Nothing then
      Throw New ArgumentNullException("クロス材")
    End If
  End Set

[ツリー表示へ]
タイトルRe^6: 配列とクラス
記事No5337
投稿日: 2007/04/13(Fri) 08:45
投稿者ひでと
ありがとうございます。
> メンバが[板厚]だけであれば、それをコンストラクタで受け取れる様にして、
メンバにはいくつか候補があります。

> > Set(ByVal value As List(Of クロス材))
> >   newクロス材 = value
> > End Set
> この場合、外部から「Nothing」がセットされる可能性もありますので、
> 何らかの対処が必要になるかも知れません。
教えていただいて初めて考えました。仰るとおり、特別な場合ですが、確かにクロス材をもっていない場合があります。
こういうことを、見通す力が大事なのだと感じました。ありがとうございました。

[ツリー表示へ]