こんばんは。きわさです。
C#のEnumの話です。
前回説明した「拡張メソッド」を使います。
まず例えば下記のようなEnumを用意します。
public enum TestType { NONE, TYPE1, TYPE2, TYPE3, }
Enum型を使っているとき、次のように各値を文字列に変換したい場合はどうしますか?
TestType.NONE : なし
TestType.TYPE1 : タイプ1
TestType.TYPE2 : タイプ2
TestType.TYPE3 : タイプ3
もしかしたら下記のような、TestTypeを受け取ってswitchで分岐させて文字列を取得するかもしれません。
public string GetName(TestType type) { var name = string.Empty; switch (type) { case TestType.NONE: name = "なし"; break; .... default: break; } return name; }
あるいは、switchではなくDictionaryを使うかもしれません。
private Dictionary<TestType, string> dic = new Dictionary<TestType, string>() { { TestType.NONE, "なし" }, { TestType.TYPE1, "タイプ1" }, { TestType.TYPE2, "タイプ2" }, { TestType.TYPE3, "タイプ3" }, }; public string GetName(TestType type) { return dic.ContainsKey(type) ? dic[type] : string.Empty; }
しかし、もしTestType型定義に新たな値が増えたら?
この処理やらDictionaryも手を入れなければなりません。
また、別のEnum型でも同様のことをしたくなった場合は?
同様の処理を書かなくてはなりません。
そこで、拡張メソッドを使って書いてみます。
public enum TestType { [Description("なし")] NONE, [Description("タイプ1")] TYPE1, [Description("タイプ2")] TYPE2, [Description("タイプ3")] TYPE3, } public static class Extension { public static string ToName(this Enum src) { var name = string.Empty; var member = src.GetType().GetMember(src.ToString()); if (member.Any()) { var attributes = member[0].GetCustomAttributes(typeof(DescriptionAttribute), false); if (attributes.Any()) { name = ((DescriptionAttribute)attributes[0]).Description; } } return name; } }
まず、Enumの定義のところで[Description]という属性を追加します。
これは Description でなくても自前の属性でも大丈夫です。
続いて、Enumの拡張メソッドを作成します。
src.GetType().GetMember(src.ToString());
で、メンバー情報を取得します。
GetCustomAttributesでDescription属性の情報を取得しています。
他の属性の場合はここも変更します。
そして、nameにDescription属性の値を入れて返しています。
この方法であれば、TestTypeに新たな定義を追加する際に処理を変更する必要もなく、
他のEnumを追加したときもまた、変更が不要となり、
Enumは下記のように、文字列を取得できるようになります。
public void Test() { var name = TestType.NONE.ToName(); }