Enum に別名を割り振る

そういや昔作って最近また別の用事で必要になったので、覚え書き程度にぺたぺた

C# 3.0 以降専用... だけど、GetAlias() を拡張メソッドにしなければ 2.0 以前でもいけるはず
と思ったら自動プロパティとか var とか使ってました。まぁいいや。

/// <summary>
/// Enum の各要素に別名を与えます。
/// </summary>
[AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
public sealed class AliasAttribute : Attribute {
    /// <summary>
    /// Enum の各要素に別名を与えます。
    /// </summary>
    /// <param name="names">与える別名。</param>
    public AliasAttribute(params string[] names) {
        this.Names = names;
    }

    /// <summary>
    /// 別名を取得します。
    /// </summary>
    public string[] Names { get; private set; }
}

/// <summary>
/// Enum の別名を取得します。
/// </summary>
public static class EnumExtender {
    /// <summary>
    /// フィールドの別名を取得します。AliasAttribute が指定されていない場合は String.Empty が返ります。
    /// </summary>
    /// <typeparam name="T">取得する型。</typeparam>
    /// <param name="value">フィールド。</param>
    /// <returns></returns>
    public static string GetAlias<T>(this T value) where T : struct {
        return GetAlias(value, 0, "");
    }

    /// <summary>
    /// フィールドの別名を取得します。AliasAttribute が指定されていない場合は String.Empty が返ります。
    /// </summary>
    /// <typeparam name="T">取得する型。</typeparam>
    /// <param name="value">フィールド。</param>
    /// <param name="index">取得するインデックス。</param>
    /// <returns></returns>
    public static string GetAlias<T>(this T value, int index) where T : struct {
        return GetAlias(value, index, "");
    }

    /// <summary>
    /// フィールドの別名を取得します。
    /// </summary>
    /// <typeparam name="T">取得する型。</typeparam>
    /// <param name="value">フィールド。</param>
    /// <param name="defaultValue">AliasAttribute が定義されていなかった場合のデフォルト値。</param>
    /// <returns></returns>
    public static string GetAlias<T>(this T value, string defaultValue) where T : struct {
        return GetAlias(value, 0, defaultValue);
    }

    /// <summary>
    /// フィールドの別名を取得します。
    /// </summary>
    /// <typeparam name="T">取得する型。</typeparam>
    /// <param name="value">フィールド。</param>
    /// <param name="index">取得するインデックス。</param>
    /// <param name="defaultValue">AliasAttribute が定義されていなかった場合のデフォルト値。</param>
    /// <returns></returns>
    public static string GetAlias<T>(this T value, int index, string defaultValue) where T : struct {
        var field = value.GetType().GetField(value.ToString());
        if (field == null) return defaultValue;

        var attr = Attribute.GetCustomAttribute(field, typeof(AliasAttribute)) as AliasAttribute;
        if (attr == null || attr.Names.Length <= index) {
            return defaultValue;
        } else {
            return attr.Names[index];
        }
    }
}