こんばんは。きわさです。
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();
}
