C#のEnum型から文字列に変換する

こんばんは。きわさです。

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();
}

スポンサーリンク