C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.83897 の関連記事表示

<< 0 >>
■83897  構造体の入れ子
□投稿者/ Oboe2001 -(2017/04/21(Fri) 09:44:05)

    分類:[VB.NET/VB2005 以降] 

    VB2017で、構造体/クラスを「入れ子構造」で使おうとしています。

    Module Module1
    '果物
    Public Class Cls_Fruit
    Public Apple(7) As Integer
    Public Orange(7) As Integer
    End Class
    '野菜
    Public Class Cls_Vegitable
    Public Cabbage(7) As Integer
    Public Carrot(7) As Integer
    End Class
    '食材
    Public Class Cls_Food
    Public Fruit(1) As New Cls_Fruit
    Public Vegitable(1) As New Cls_Vegitable
    End Class
    'クラスを使って変数を宣言
    Public Food As New Cls_Food
    End Module

    VB6までは、Typeで宣言すれば入れ子構造を作ることができました。VB.NET以降では
    TypeではなくStructureやClassを使えば良さそうだ、ということまでは分かりました。

    しかしながら、「食材」のところで、「BC30053 配列を'New'で宣言することはできま
    せん」と怒られてしまいます。

    Food.Fruit(1).Apple(7) = 100 ……のような使い方をしたいのですが、どのように
    宣言すれば良いのでしょうか。
親記事 /過去ログ143より / 関連記事表示
削除チェック/

■83898  Re[1]: 構造体の入れ子
□投稿者/ 魔界の仮面弁士 -(2017/04/21(Fri) 10:21:16)
    2017/04/21(Fri) 10:26:25 編集(投稿者)

    No83897 (Oboe2001 さん) に返信
    > VB6までは、Typeで宣言すれば入れ子構造を作ることができました。VB.NET以降では
    > TypeではなくStructureやClassを使えば良さそうだ、ということまでは分かりました。

    VB4〜VB6 でも、クラスの入れ子はできますね。
    Class ステートメントではなく、*.cls ファイルでの宣言になりますが。


    > しかしながら、「食材」のところで、「BC30053 配列を'New'で宣言することはできま
    > せん」と怒られてしまいます。

    要素数を指定して宣言すれば、それだけで配列のインスタンスが生成されますので、
    New を使う必要が無いという事です。下記の 4 つはいずれも同じ意味です。


    ★案1★
    Public Class Cls_Food
     Public Fruit(1) As Cls_Fruit
     Public Vegitable(1) As Cls_Vegitable
    End Class


    ★案2★
    Public Class Cls_Food
     Public Fruit() As Cls_Fruit
     Public Vegitable() As Cls_Vegitable
     Public Sub New()
      ReDim Fruit(1), Vegitable(1)
     End Sub
    End Class

    ★案3★
    Public Class Cls_Food
     Public Fruit() As Cls_Fruit = New Cls_Fruit() {Nothing, Nothing}
     Public Vegitable() As Cls_Vegitable = New Cls_Vegitable() {Nothing, Nothing}
    End Class

    ★案4★
    Public Class Cls_Food
     Public Fruit() As Cls_Fruit = New Cls_Fruit(1) {}
     Public Vegitable() As Cls_Vegitable = New Cls_Vegitable(1) {}
    End Class


    > Food.Fruit(1).Apple(7) = 100 ……のような使い方をしたいのですが、
    Cls_Fruit が、VB.NET の「構造体(Strucutre)」や VB6 の「ユーザー定義型(Type)」ではなく、
    Cls_Fruit が、VB.NET の「クラス(Class)」や VB6 の「クラス」として宣言されていた場合、
    単に配列を確保しただけでは、個々の要素の初期値は Nothing になっています。

    ですからクラスの配列であった場合には、VB6 でいうところの
     ReDim Food.Fruit(1)
     Set Food.Fruit(0) = New Cls_Fruit
     Set Food.Fruit(1) = New Cls_Fruit
    のような処理が事前に必要です。


    配列要素の初期化も併せて行うならこんな感じ。
    今回は 0 To 1 な 2 要素な配列だけなので、直接書いてみます。

    ★案5★
    Public Class Cls_Food
     Public Fruit() As Cls_Fruit = {New Cls_Fruit(), New Cls_Fruit()}
     Public Vegitable() As Cls_Vegitable = {New Cls_Vegitable(), New Cls_Vegitable()}
    End Class

    配列の要素数が多い場合は、初期化処理をコンストラクタ内で
    ループ生成した方が良いでしょう。
記事No.83897 のレス /過去ログ143より / 関連記事表示
削除チェック/

■83903  Re[1]: 構造体の入れ子
□投稿者/ 大谷刑部 -(2017/04/21(Fri) 11:32:45)
    No83897 (Oboe2001 さん) に返信
    > VB2017で、構造体/クラスを「入れ子構造」で使おうとしています。
    >
    > Module Module1
    > '果物
    > Public Class Cls_Fruit
    > Public Apple(7) As Integer
    > Public Orange(7) As Integer
    > End Class
    > '野菜
    > Public Class Cls_Vegitable
    > Public Cabbage(7) As Integer
    > Public Carrot(7) As Integer
    > End Class
    > '食材
    > Public Class Cls_Food
    > Public Fruit(1) As New Cls_Fruit
    > Public Vegitable(1) As New Cls_Vegitable
    > End Class
    > 'クラスを使って変数を宣言
    > Public Food As New Cls_Food
    > End Module
    >
    > VB6までは、Typeで宣言すれば入れ子構造を作ることができました。VB.NET以降では
    > TypeではなくStructureやClassを使えば良さそうだ、ということまでは分かりました。

    上記でやりたいことであれば構造体で十分な気がしますが、
    Classを使いたい理由は何でしょう?
    VB6でTypeで使っていた変数を移植したいだけなら、
    構造体を使った方が明らかに簡単だと思います。

    今後、プロパティーやメソッドの機能を増やしたいなら、当然クラスという選択肢になりますが、
    何でもかんでもクラスにする必要はないと思います。


記事No.83897 のレス /過去ログ143より / 関連記事表示
削除チェック/

■83905  Re[2]: 構造体の入れ子
□投稿者/ Hongliang -(2017/04/21(Fri) 11:48:31)
    > 上記でやりたいことであれば構造体で十分な気がしますが、
    > Classを使いたい理由は何でしょう?

    > 何でもかんでもクラスにする必要はないと思います。

    個人的には逆で、「Classで十分」であり、「Structureを使いたい理由」を考えるようにしています。
    VB6は触ったことがないので、Typeとの互換性という文脈では何も言えませんが…。
記事No.83897 のレス /過去ログ143より / 関連記事表示
削除チェック/

■83907  Re[3]: 構造体の入れ子
□投稿者/ Oboe2001 -(2017/04/21(Fri) 13:04:17)
    No83898 (魔界の仮面弁士さん) に返信

     インスタンスの生成や、Newを使った配列要素の初期化の方法について、大変参考になりました。無事プログラムが動作を初め大変感謝しています。
     
    No83903 (大谷刑部さん) に返信

     最初は構造体でプログラムを作り始めたのですが、宣言の中で要素の数を記述するとエラーになってしまったので、クラスに書き直した次第です。

    No83905 (Hongliang さん) に返信

     構造体とクラスのどちらを選択するべきかについて、私は勉強不足であると痛感しました。あまりにもVB6を使っていた期間が長すぎたのだと思います。

     皆様ありがとうございます。
記事No.83897 のレス / END /過去ログ143より / 関連記事表示
削除チェック/

■83909  Re[4]: 構造体の入れ子
□投稿者/ 魔界の仮面弁士 -(2017/04/21(Fri) 13:22:19)
記事No.83897 のレス / END /過去ログ143より / 関連記事表示
削除チェック/

■83912  Re[4]: 構造体の入れ子
□投稿者/ 大谷刑部 -(2017/04/21(Fri) 18:27:53)
    No83907 (Oboe2001 さん) に返信
    >  構造体とクラスのどちらを選択するべきかについて、私は勉強不足であると痛感しました。あまりにもVB6を使っていた期間が長すぎたのだと思います。

    VB6が長すぎたとかはあんまり関係ないと思います。

    http://dobon.net/vb/dotnet/beginner/whenusestruct.html

    にも、配列変数として使用する場合は構造体のメリットが大きいと記載されています。

    >参照型の配列の場合、要素のインスタンスはメモリにバラバラに置かれます。一方値型の配列は、要素のインスタンスが一塊で(インラインで)メモリに置かれます。そのため、構造体の配列の方が要素の読み込みと書き込みの効率がよく、さらにガベージコレクションの負担が少ないです。

    実際一般論としてVB6のTypeを使っているケースも
    大半がこれに該当すると思います。
    プロパティーもメソッドも存在するケースは、
    クラスの方が圧倒的にいいと思いますが、

    VB6のTypeの後継が構造体であることを考慮すると、
    VB6でTypeで宣言されているのが最適だったものは、構造体に置き換える方がいい場合が多い
    というだけです。

    もっとも配列 + 構造体の代わりに
    クラス + コレクションを使っているケースもあり、
    VB6の時代からインデックス→名称取出とかができるので、
    (配列 + 構造体ならループになる)
    クラス + コレクションを推奨している人もおり、
    そのどちらかがいいとなるとわかりません。

    なので、元のロジックがVB6で配列 + 構造体で適当だったかどうかの検証は
    必要と思います。


記事No.83897 のレス / END /過去ログ143より / 関連記事表示
削除チェック/

■83922  Re[1]: 構造体の入れ子
□投稿者/ Jitta -(2017/04/24(Mon) 19:35:26)
    No83897 (Oboe2001 さん) に返信
    > VB2017で、構造体/クラスを「入れ子構造」で使おうとしています。
    > 
    > Module Module1
    >     '果物
    >     Public Class Cls_Fruit
    >         Public Apple(7) As Integer
    >         Public Orange(7) As Integer
    >     End Class
    >     '野菜
    >     Public Class Cls_Vegitable
    >         Public Cabbage(7) As Integer
    >         Public Carrot(7) As Integer
    >     End Class
    >     '食材
    >     Public Class Cls_Food
    >         Public Fruit(1) As New Cls_Fruit
    >         Public Vegitable(1) As New Cls_Vegitable
    >     End Class
    >     'クラスを使って変数を宣言
    >     Public Food As New Cls_Food
    > End Module
    > 
    > Food.Fruit(1).Apple(7) = 100 ……のような使い方をしたいのですが、どのように
    
    気になる。
    AppleとOrangeがともに7なのは何故?
    偶然、それとも必然?
    えーっと、構造体のメンバーは全て同じ大きさの配列なのか?ってこと。
    ここにあるのは皆同じになっている。
    だったら、メンバーを配列にするのではなく、
    構造体の実態を配列にする方が扱いやすいのでは?
記事No.83897 のレス / END /過去ログ143より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -