none
HashtableとEnumについて RRS feed

  • 質問

  •  

    コード ブロック

      enum hoge
      {
       a = 0,
       b = 1
      }

     

    Hashtable ht = new Hashtable();

    ht["sunday"] = hoge.b; //とすると "b" が入ってしまいます。

     

    ht["sunday"] = Enum.Format(typeof(hoge),hoge.b,"d");  //と書くと "1"が入ります。

     

     

    ハッシュテーブルにenumの値 0,1,2.....を入れたい場合の質問です。

    もっとスマートに記述する方法はありますでしょうか?

    よろしくおねがいします。

    2008年1月8日 3:54

回答

  • 外池です。

     

    あぁ・・・、HashTableの中に、いろんな型のデータがゴチャゴチャに入ってしまっているわけですか。で、それが、既存のやり方だと。

     

    であればですね、とにかく、htにはどんどんデータを放り込んで、「取り出すとき」に検査してやれば良いかと。

     

    ht["sunday"]=hoge.bは、そのままにしておく。

     

    取り出しのときに、ht["sunday"]の型を調べて(それがhoge型かどうか?)

    で、(Int)のキャスト演算子を使ってやれば良いかと。

     

     

     

    2008年1月8日 6:00
  • 外池さんレスありがとうございます!

     

    >ht["sunday"]=hoge.bは、そのままにしておく。

    >で、(Int)のキャスト演算子を使ってやれば良いかと。

     

    おお!そうですね!

    ht["sunday"]=hoge.b

    として入れておいて

    Convert.ToInt32(ht["sunday"])

    or

    (int)ht["sunday"]

    として取り出せばいいですね!

     

    そのまま「1」が得られると面倒でないのになぁ

     

    >ht["sunday"]の型を調べて(それがhoge型かどうか?)

    は ht["sunday"].GetType() で確認できるよ

    という事ですね。

     

     

    2008年1月8日 6:16
  • そのまま「1」が得られると面倒でないのになぁ

    勝手に型を変えられたら困りますし。

     

    ht["sunday"].GetType() で確認できるよ

    is 演算子ってのがあります。

    // 列挙型は値型なので使えないですが、より好ましい as 演算子ってのもあります。

    2008年1月8日 6:40
  • Hongliangさんレスありがとうございます。

    >勝手に型を変えられたら困りますし。

    確かにそうですね。 hoge.b という型が入っているのであって

    値「1」 がハッシュテーブルに入っている訳ではないのですからね。

    少し混同していたみたいです;(

     

    >is 演算子ってのがあります

    成るほど

    ht["sunday"] is hoge  -> Trueですね。

     

    >列挙型は値型なので使えないですが

    あ、本当だ

    ht["sunday"] as hoge で

    as オペレータは参照型で使用してください

    とコンパイルエラーになりました。

    色々勉強になりましたm(__)m

     

     

    2008年1月8日 7:15

すべての返信

  • どんな型の値が入ればいいのかよく分かりませんね。

    hoge.b を直接代入した場合、Hashtable には hoge.b という値が入ります。Hashtable から取り出したら hoge 型にキャストしてそれを使うことができます。その後 int にキャストすることも可能です。

    (int)hoge.b を代入した場合、Hashtable には hoge.b が指す int 型の値が入ります。Hashtable から取り出したら int にキャストすることになります。

    ((int)hoge.b).ToString() を代入すれば、Hashtable には hoge.b が指す int 型の値を 10進で文字列化した string 型の値が入ります。当然、Hashtable から取り出したあとのキャスト先は string 型です。Enum.Format も返値は string ですから結果的にはこれになりますね。

     

    列挙型使うのならそのまま列挙型の値として入れるのが一般的だと思いますが。

    2008年1月8日 4:47
  • 外池と申します。

     

    「"b"がはいってしまいます」と「"1"が入ります」という表現をされていることから、htの個々のvalueにどんな型で格納されているか、ゴチャゴチャになってしまっているようにお見受けします。

     

    「"b"がはいってしまいます」と表現されている方について、いくみさんは文字列型の"b"が格納されていると誤解されていませんでしょうか? 実際には、hoge型のbという値が格納されています。私は、これは、これで、意図されている通りの動作であって、まったく問題ないと思います。ここから1という値を取り出したいのであれば、ht["sunday"]から返るhoge型の値をInt32型へキャストすれば良いと思います。

     

    「"1"が入ります」と表現されている方は、これは、Enum.Format関数が返す文字列型としての"1"が入ってしまっており、たぶん、せっかくhoge型を定義しているのに無関係な型で格納されてしまっています。これは、そもそも意図されていることに反していませんか?

     

    ------

     

    で、この辺りの理解が整理されたら、あらためて、hoge型の値のみをとるような独自のクラスをHashtable型から導出されることをお奨めします。Hashtableの個々の要素は、keyもvalueもObject型をとる非常に汎用なものであって、もし、独自に定義するhoge型のみをvalueにとるのであれば、そのように「縛り」をきつくした方が、後のプログラミングが安全になります。あとkeyとしても、文字型だけなのかどうか、同じく検討されてみてはいかがでしょうか?

     

    2008年1月8日 4:56
  • Hongliang さんレスありがとうございます。

    >どんな型の値が入ればいいのかよく分かりませんね。

     

    前述の通り

    >>ハッシュテーブルにenumの値 0,1,2.....を入れたい場合の質問です。

     

    >Enum.Format も返値は string ですから

    ああ、そうですね!ちょっと勘違いしていました。

     

    ht["sunday"] = Convert.ToInt32(hoge.b)

    先例は こう書いておくべきでしたね。

    でもご指摘の通り int型を入れることになりますね。

     

    >列挙型使うのならそのまま列挙型の値として入れるのが一般的だと思いますが。

    既存のプログラムが何でもかんでもハッシュテーブルに入れてあるのです;<

     

    質問の仕方が不味かったので改めて完結にレスします。

     

    2008年1月8日 5:43
  • 外池さんレスありがとうございます。

     

    >「"b"がはいってしまいます」と表現されている方について、いくみさんは文字列型の"b"が格納されていると誤解されていませんでしょうか?

    いえ、 hoge.b が入ってると認識しています。

     

    >Enum.Format関数が返す文字列型としての"1"が入ってしまっており

    Hongliang さんにも指摘されましたが、其のとおりですね。

    ht["sunday"] = Convert.ToInt32(hoge.b) と書くべきでした。

     

    >独自に定義するhoge型のみをvalueにとるのであれば、

    >そのように「縛り」をきつくした方が、後のプログラミングが安全になります

    まったく同じ見解ですが、既存のプログラムを作った人が

    引き渡したいデータを全部HashTableに突っ込んでいるのです;<

    簡単に書きますとDatabaseに入れたいものを全部です;(

    HashTableはゴミ箱じゃないんですけどね・・・

     

    2008年1月8日 5:54
  • 私の質問の例が悪かったですm(__)m

     

    ht["sunday"] = hoge.b;

    として

    私としては 入れた hoge.b は 1 という認識だったのですが
    ht["sunday"] として取り出すと 私の予想では「1」 が得られると思っていたのですが

    文字列"b" が得られてしまいます。(予想に反してました)

    ここで「1」 を得たいのです。

     

    ht["sunday"] = Convert.ToInt32(hoge.b)

    として

    ht["sunday"]  として取り出すと「1」が得られるのですが

    わざわざ Convertとか書かずにスマートに記述出来ないものかなと思い

    Enum.Perse、Enum.Formatなどを調べていたのです。

    2008年1月8日 5:56
  • 外池です。

     

    あぁ・・・、HashTableの中に、いろんな型のデータがゴチャゴチャに入ってしまっているわけですか。で、それが、既存のやり方だと。

     

    であればですね、とにかく、htにはどんどんデータを放り込んで、「取り出すとき」に検査してやれば良いかと。

     

    ht["sunday"]=hoge.bは、そのままにしておく。

     

    取り出しのときに、ht["sunday"]の型を調べて(それがhoge型かどうか?)

    で、(Int)のキャスト演算子を使ってやれば良いかと。

     

     

     

    2008年1月8日 6:00
  • 外池さんレスありがとうございます!

     

    >ht["sunday"]=hoge.bは、そのままにしておく。

    >で、(Int)のキャスト演算子を使ってやれば良いかと。

     

    おお!そうですね!

    ht["sunday"]=hoge.b

    として入れておいて

    Convert.ToInt32(ht["sunday"])

    or

    (int)ht["sunday"]

    として取り出せばいいですね!

     

    そのまま「1」が得られると面倒でないのになぁ

     

    >ht["sunday"]の型を調べて(それがhoge型かどうか?)

    は ht["sunday"].GetType() で確認できるよ

    という事ですね。

     

     

    2008年1月8日 6:16
  • そのまま「1」が得られると面倒でないのになぁ

    勝手に型を変えられたら困りますし。

     

    ht["sunday"].GetType() で確認できるよ

    is 演算子ってのがあります。

    // 列挙型は値型なので使えないですが、より好ましい as 演算子ってのもあります。

    2008年1月8日 6:40
  • Hongliangさんレスありがとうございます。

    >勝手に型を変えられたら困りますし。

    確かにそうですね。 hoge.b という型が入っているのであって

    値「1」 がハッシュテーブルに入っている訳ではないのですからね。

    少し混同していたみたいです;(

     

    >is 演算子ってのがあります

    成るほど

    ht["sunday"] is hoge  -> Trueですね。

     

    >列挙型は値型なので使えないですが

    あ、本当だ

    ht["sunday"] as hoge で

    as オペレータは参照型で使用してください

    とコンパイルエラーになりました。

    色々勉強になりましたm(__)m

     

     

    2008年1月8日 7:15