none
Dictionaryの検索で、指定したKeyと違う値が返ってくる。 RRS feed

  • 質問

  • いろんなサイトを巡っていたのですが、どこにもなかったので書込みいたしました。

    現在C#でDictionaryを使って、KeyをString、Valueを自作したクラスにしています。

    KeyのStringには、16進数を表した文字列を格納しています。

    Keyに02-FE-00-00-31-00-50-30と、02-FE-00-00-31-00-50-2Fを格納しているのですが、

    検索時に、02-FE-00-00-31-00-50-2Fを指定して検索すると、02-FE-00-00-31-00-50-30が取得されてしまいます。

    取得方法は、get = openWith["02-FE-00-00-31-00-50-2F"] 

    上記のように記載して、取得しています。初歩的な質問スレで申し訳ないです。

    よろしくお願いいたします。

    2018年3月23日 8:14

回答

  • > このString が原因でした。本来は string で、動作させたところ正しく動作しました。

    言語は C# ですよね? で、String の S が大文字だったのが原因で、小文字の string にしたら解消したといってます?

    そんなことは絶対なくて、他のところに原因があったはずです。(多分、Azulean さんが言われている「ItemClass と Itemclass は異なる」というところではないかと思います)

    ちなみに、.NET の型としては String なのですが、C# ではエイリアス(別名)として string も使えます。Int32 の int、Boolean の bool なども同様です。

    2018年3月26日 3:59
  • そのコードはコンパイルが通りません。

    • Dictionary<TKey, TValue>.Add には引数が2つ必要となるが、1つしか指定されていない
    • ItemClass という未定義の値を渡している
    • C# は大文字小文字を区別するので ItemClass と Itemclass は異なるものとなるが、混在している

    再現できる、コンパイルが通るコードを書いて欲しいです。

    なお、Add した後に new し直していない=別の参照に変えていないのであれば、書き換わることはあり得ます。

    2018年3月23日 9:19
    モデレータ
  • public Dictionary<String, Itemclass> dic = new Dictionary<String, Itemclass>();

    このString が原因でした。本来は string で、動作させたところ正しく動作しました。

    すでに指摘されているが、あり得ません。
    C# のキーワード string はコンパイル時に System.String と解釈されます。
    極端な話、以下のように左辺と右辺で大文字小文字が違ってもコンパイルが通ります。

    public Dictionary<String, int> dic = new Dictionary<string, int>();

    つまり、その小文字にするという修正は「修正前と後が同じもの」と言うことになります。
    その修正によって直ったということは、試行錯誤していた別の何かが効いたことになるのでしょう。

    2018年3月26日 11:59
    モデレータ

すべての返信

  • Windows 7 SP1, Visual Studio Community 2017 (15.226430.13), .NET Framework 4.6.1

    で試しましたが再現しません。

    なんとなーくですが、こんなコード書いてません? デバッガで、withOpenの"...2f"のキーと"...30"のキーに格納されている値を確認してみてください。

    var obj = new Hoge();
    hoge.Name = "2f";
    openWith["02-2F"] = hoge;
    hoge.Name = "30";
    openWith["02-30"] = hoge;
    2018年3月23日 8:35
  • Windows 7 SP1, Visual Studio Community 2017 (15.226430.13), .NET Framework 4.6.1

    で試しましたが再現しません。

    なんとなーくですが、こんなコード書いてません? デバッガで、withOpenの"...2f"のキーと"...30"のキーに格納されている値を確認してみてください。

    var obj = new Hoge();
    hoge.Name = "2f";
    openWith["02-2F"] = hoge;
    hoge.Name = "30";
    openWith["02-30"] = hoge;

    返信いただきありがとうございます。

    C#で記載したコードですが、

     public Dictionary<String, Itemclass> dic = new Dictionary<String, Itemclass>();

    Item Item = new Itemclass();

    Item .ID = "02-FE-00-00-31-00-50-2F";

    Item .Name = "test type";

    dic.add(ItemClass);

    Item = new ItemClass();

    Item .ID = "02-FE-00-00-31-00-50-30";

    Item .Name = "Case";

    dic.add(ItemClass);

    //取得時

    Itemclass Item = new Itemclass();

    Item = dic["02-FE-00-00-31-00-50-2F"];

    このItemに入っている値が、02-FE-00-00-31-00-50-30でAddした値になってしまいます。

    申し訳ございません、、、デバッガの使い方がわからないので助言いただいた確認ができませんでした。。。

    2018年3月23日 9:07
  • >>申し訳ございません、、、デバッガの使い方がわからないので助言いただいた確認ができませんでした。。。

      勘違いしていました。

      ウォッチ式で、値を確認しましたがIDとNameには自分が意図した値が格納されていました。

    2018年3月23日 9:14
  • そのコードはコンパイルが通りません。

    • Dictionary<TKey, TValue>.Add には引数が2つ必要となるが、1つしか指定されていない
    • ItemClass という未定義の値を渡している
    • C# は大文字小文字を区別するので ItemClass と Itemclass は異なるものとなるが、混在している

    再現できる、コンパイルが通るコードを書いて欲しいです。

    なお、Add した後に new し直していない=別の参照に変えていないのであれば、書き換わることはあり得ます。

    2018年3月23日 9:19
    モデレータ
  • ソース記載にあたり、検証しずらいソースを書いてしまい申し訳ございませんでした。

    問題についてですが、解決しました。

    原因は、単純なことでご指摘の通り、大文字と小文字の問題でした。

    public Dictionary<String, Itemclass> dic = new Dictionary<String, Itemclass>();

    このString が原因でした。本来は string で、動作させたところ正しく動作しました。

    ご対応いただき、ありがとうございました。

    2018年3月26日 2:40
  • > このString が原因でした。本来は string で、動作させたところ正しく動作しました。

    言語は C# ですよね? で、String の S が大文字だったのが原因で、小文字の string にしたら解消したといってます?

    そんなことは絶対なくて、他のところに原因があったはずです。(多分、Azulean さんが言われている「ItemClass と Itemclass は異なる」というところではないかと思います)

    ちなみに、.NET の型としては String なのですが、C# ではエイリアス(別名)として string も使えます。Int32 の int、Boolean の bool なども同様です。

    2018年3月26日 3:59
  • public Dictionary<String, Itemclass> dic = new Dictionary<String, Itemclass>();

    このString が原因でした。本来は string で、動作させたところ正しく動作しました。

    すでに指摘されているが、あり得ません。
    C# のキーワード string はコンパイル時に System.String と解釈されます。
    極端な話、以下のように左辺と右辺で大文字小文字が違ってもコンパイルが通ります。

    public Dictionary<String, int> dic = new Dictionary<string, int>();

    つまり、その小文字にするという修正は「修正前と後が同じもの」と言うことになります。
    その修正によって直ったということは、試行錯誤していた別の何かが効いたことになるのでしょう。

    2018年3月26日 11:59
    モデレータ