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

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

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

No.97702 の関連記事表示

<< 0 >>
■97702  VB.NetのDictionaryについて
□投稿者/ ぴっぴ -(2021/07/01(Thu) 22:06:57)

    分類:[.NET 全般] 

    VB.NetのDictionaryについて質問です。

    Dim dic As Dictionary(Of Integer, List(Of 自作クラス)) = New Dictionary(Of Integer, List(Of 自作クラス))
    というようにDictionaryを作成しました。

    このDictionaryには、自作クラスが格納されたListをAddして追加しているのですが
    このDictionaryからの値の取得がうまくいかず困っています。

    Dictionaryに要素を追加する際は以下のように書いています。
    dic.Add(i, lsttData)
    ※iはFor文のループカウンタ、lsttDataは自作クラスが格納されたListです。

    Dictionaryから値を取得する部分は以下のように書いています。
    Dim lst As List(Of 自作クラス) = dic(i)
    ※iはFor文のループカウンタ

    このように取得すると、Dictionary内のすべてのListの値が取得されてしまいます。
    Keyと一致する値のみ取得したいのですが、どのに問題があるのかわかりません。

    VB.Netのフレームワークは4.7.2です。
    どなたか詳しい方、よろしくお願いします。
親記事 /過去ログ169より / 関連記事表示
削除チェック/

■97704  Re[1]: VB.NetのDictionaryについて
□投稿者/ Azulean -(2021/07/01(Thu) 23:38:30)
    2021/07/01(Thu) 23:42:16 編集(投稿者)

    No97702 (ぴっぴ さん) に返信
    > Dictionaryに要素を追加する際は以下のように書いています。
    > dic.Add(i, lsttData)
    > ※iはFor文のループカウンタ、lsttDataは自作クラスが格納されたListです。

    lsttData は New しなおしていますか?
    List (Of 自作クラス) の New が一度だけの場合、すべての i で同じ 1 つの List (Of 自作クラス) を設定しています。


    dic.Add は lsttData をコピーする(そのときの状態を覚える)のではなく、「参照」を追加します。
    たとえて言えば、「倉庫の住所」を追加しておき、「倉庫」に何が入っているかは覚えません。
    1 つの「倉庫」をみんなが使うので、どの i であっても「すべてが入った倉庫」=List になります。


    参照型について改めて勉強していただいた方が良いかもしれません。
    https://dobon.net/vb/dotnet/beginner/valuereference.html
記事No.97702 のレス /過去ログ169より / 関連記事表示
削除チェック/

■97707  Re[2]: VB.NetのDictionaryについて
□投稿者/ ぴっぴ -(2021/07/02(Fri) 09:21:26)
    No97704 (Azulean さん) に返信
    > 2021/07/01(Thu) 23:42:16 編集(投稿者)
    >
    > ■No97702 (ぴっぴ さん) に返信
    >>Dictionaryに要素を追加する際は以下のように書いています。
    >>dic.Add(i, lsttData)
    >>※iはFor文のループカウンタ、lsttDataは自作クラスが格納されたListです。
    >
    > lsttData は New しなおしていますか?
    > List (Of 自作クラス) の New が一度だけの場合、すべての i で同じ 1 つの List (Of 自作クラス) を設定しています。
    >
    >
    > dic.Add は lsttData をコピーする(そのときの状態を覚える)のではなく、「参照」を追加します。
    > たとえて言えば、「倉庫の住所」を追加しておき、「倉庫」に何が入っているかは覚えません。
    > 1 つの「倉庫」をみんなが使うので、どの i であっても「すべてが入った倉庫」=List になります。
    >
    >
    > 参照型について改めて勉強していただいた方が良いかもしれません。
    > https://dobon.net/vb/dotnet/beginner/valuereference.html

    おっしゃる通りでした。
    わかりやすい例えありがとうございます。
    参照型について勉強し直します。
    ありがとうございました!
記事No.97702 のレス / END /過去ログ169より / 関連記事表示
削除チェック/

■97706  Re[1]: VB.NetのDictionaryについて
□投稿者/ 魔界の仮面弁士 -(2021/07/02(Fri) 09:16:05)
    No97702 (ぴっぴ さん) に返信
    > Dim dic As Dictionary(Of Integer, List(Of 自作クラス)) = New Dictionary(Of Integer, List(Of 自作クラス))
    > というようにDictionaryを作成しました。
    > dic.Add(i, lsttData)

    たとえば、Dictionary(Of Integer, ListBox) を想像してみてください。
     dic.Add(0, Me.ListBox1)
     dic.Add(1, Me.ListBox1)
    とした場合、ListBox1 という同一のインスタンスが Key 0 と Key 1 で共有されます。

    この状態で、
     dic(1).Items.Add("New Item")
    とすれば、Me.ListBox1 に対する操作となるわけですから、
    dic(1).Items だけでなく dic(0).Items の件数も増加しますよね。

    同一の List(Of ) インスタンスを登録していた場合も、それと同じ事が起きます。


    『空の List(Of )』を追加することが目的なら、
     dic.Add(i, New List(Of 自宅クラス)())
    のように、新しいインスタンスを追加します。


    『既存リストのコピー』を追加したい場合は、別インスタンスを生成するために、
     dic.Add(i, lsttData.ToList())
    とすることはできます。こうすることによって、
    dic(1).Add 操作を行っても、dic(0) の件数が変化しなくなります。

    また今回の場合、List(Of 自作構造体) ではなく
    List(Of 自作クラス) であるため、場合によっては、
    List(Of ) の個々のメンバーに対しても複製が必要になる可能性があります。

    たとえば List(Of FileStream) を管理していた場合、そのリストを複製するにあたり、
     「同一のファイルストリームへの参照」
     「同じファイルを共有アクセスで開いている別のストリーム」
     「別フォルダの同名ファイルを開いているストリーム」
     「同フォルダの別名ファイルを開いているストリーム」
    など、どのような複製が必要とされるかは、ケースバイケースですよね。
記事No.97702 のレス /過去ログ169より / 関連記事表示
削除チェック/

■97708  Re[2]: VB.NetのDictionaryについて
□投稿者/ ぴっぴ -(2021/07/02(Fri) 09:26:45)
    No97706 (魔界の仮面弁士 さん) に返信
    > ■No97702 (ぴっぴ さん) に返信
    >>Dim dic As Dictionary(Of Integer, List(Of 自作クラス)) = New Dictionary(Of Integer, List(Of 自作クラス))
    >>というようにDictionaryを作成しました。
    >>dic.Add(i, lsttData)
    >
    > たとえば、Dictionary(Of Integer, ListBox) を想像してみてください。
    >  dic.Add(0, Me.ListBox1)
    >  dic.Add(1, Me.ListBox1)
    > とした場合、ListBox1 という同一のインスタンスが Key 0 と Key 1 で共有されます。
    >
    > この状態で、
    >  dic(1).Items.Add("New Item")
    > とすれば、Me.ListBox1 に対する操作となるわけですから、
    > dic(1).Items だけでなく dic(0).Items の件数も増加しますよね。
    >
    > 同一の List(Of ) インスタンスを登録していた場合も、それと同じ事が起きます。
    >
    >
    > 『空の List(Of )』を追加することが目的なら、
    >  dic.Add(i, New List(Of 自宅クラス)())
    > のように、新しいインスタンスを追加します。
    >
    >
    > 『既存リストのコピー』を追加したい場合は、別インスタンスを生成するために、
    >  dic.Add(i, lsttData.ToList())
    > とすることはできます。こうすることによって、
    > dic(1).Add 操作を行っても、dic(0) の件数が変化しなくなります。
    >
    > また今回の場合、List(Of 自作構造体) ではなく
    > List(Of 自作クラス) であるため、場合によっては、
    > List(Of ) の個々のメンバーに対しても複製が必要になる可能性があります。
    >
    > たとえば List(Of FileStream) を管理していた場合、そのリストを複製するにあたり、
    >  「同一のファイルストリームへの参照」
    >  「同じファイルを共有アクセスで開いている別のストリーム」
    >  「別フォルダの同名ファイルを開いているストリーム」
    >  「同フォルダの別名ファイルを開いているストリーム」
    > など、どのような複製が必要とされるかは、ケースバイケースですよね。

    大変分かりやすい解説ありがとうございます。
    勉強になります。
記事No.97702 のレス / END /過去ログ169より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -