2006年08月15日

enumの代わり

  
C#の enum ってとても良い機能だと思うのだけれど、日本人が使おうと思うとちょっと不便。
例えば、
 public enum Gender { Male, Female }

と定義したときに、
"男性","女性" という文字列をどこに定義したらよいのかとても迷う。
ある特定のクラス内でしか使われないのだったら、
 class Person {
public string ToGenderString() { ... }
}

とでも定義しておけばよいのかもしれないが、複数のクラスで利用しようと思うと、この方法だとうまくいかない。
じゃあ、
 public enum Gender { 男性, 女性 }

って定義すれば、
 Gender gender = Gender.女性;

gender.ToString();

で文字列を求められるけど、識別名に日本語使うのは抵抗があるし、「男」、「女」
って文字列にしたい場合には、困ってしまう。

ユーティリティクラスのstaticメソッドで、
  public static string ToGenderString(Gender g) { ... }

と定義すれのも、一つの方法だけれども、それほど良い解決方法だとは思えない。

なんか良い方法はないかな〜 って随分以前に考えた方法は、enumの代わりになるクラスを定義する方法。(ソースは最後に掲載)

これならば、enumとほとんどおんなじ感覚で使えるし、ToString を override しているので、"男性", "女性" という文字列も取得できる。
ToShortStringというメソッド追加すれば、"男", "女" にも対応できる。

列挙型定義するたびに、こんな定義をするのは面倒だけれど、それなりにメリットがあると思う。
ただ、結局日の目を見なかった。

public struct Gender {
private enum EnumGender { Male, Female }
private static Gender _MaleInstance = new Gender(EnumGender.Male);
private static Gender _FemaleInstance = new Gender(EnumGender.Female);
private EnumGender _gender;
private Gender(EnumGender i) {
_gender = i;
}
public static Gender Male {
get {return _MaleInstance; }
}
public static Gender Female {
get { return _FemaleInstance; }
}
public override string ToString() {
return (_gender == EnumGender.Male) ? "男性" : "女性";
}
public static implicit operator int(Gender m) {
return (int)m._gender;
}
}


使い方は、以下のような感じ。

Gender g1 = Gender.Male;
Gender g2 = Gender.Female;
Gender g3 = g1;
Console.WriteLine(g1.ToString());
Console.WriteLine(g2.ToString());
Console.WriteLine(g3.ToString());
int n = g1;
Console.WriteLine(n);



この記事へのコメント
同じ思考でハマッタことあります。

enumプロパティの国際化(多国語対応)で障害になってました。
stract でラップ(?)するアイディアは思いつきませんでした。
とってもいいですね。

別のクラスに、ToGenderString の様なのを作っちゃうと、使いまわせなくなるし、文字リソースとデータ構造が上手に分離できず、どうにかしたかったのですが…
アイディア、参考にさせて頂きます。
Posted by t_suzuki at 2006年08月29日 18:34
参考になってなによりです。
enumの定義から、このコードを自動生成できれば、もっと便利に使えると思うのですが、そこまではやってません。
Posted by Gushwell at 2006年08月29日 23:29
私は属性を使用して対応する文字列を定義しています。
public enum Gender
{
[EnumStringAttribute("男")]
Male,
[EnumStringAttribute("女")]
Female
}
みたいな感じで。
取り出すときは、EnumStringAttributeクラスに静的なメソッドで
EnumStringAttribute.GetString(typeof(Gender),Gender.Male)
と言う風にして文字列に変換します。
Posted by kisikisi at 2006年10月17日 00:40
kisikisi さん、コメントありがとうございます。
実は僕も属性を使った方法に行き着きました。
このコードについても時間が空いたときに紹介したいと思います。

Posted by Gushwell at 2006年10月17日 22:44
 

この記事へのトラックバックURL

この記事へのトラックバック
待ち記事来たらず。必要に迫られたので書いてみる。 窓際プログラマーの独り言:enumの代わり リンク先は、enum の値から、それに対応する日本語の文字列を取り出したいときにどうするか、というエントリであるが、コメント欄で kisikisi さんがちらり言
[C#] enum に文字列の属性を【いげ太のブログ】at 2007年11月23日 21:06