web-dev-qa-db-ja.com

値からC#の列挙型の説明を取得する方法?

可能な重複:
Enumの価値の属性を取得する

このようなDescription属性を持つ列挙型があります。

public enum MyEnum
{
    Name1 = 1,
    [Description("Here is another")]
    HereIsAnother = 2,
    [Description("Last one")]
    LastOne = 3
}

Enumに基づいて説明を取得するためのこのコードが見つかりました

public static string GetEnumDescription(Enum value)
{
    FieldInfo fi = value.GetType().GetField(value.ToString());

    DescriptionAttribute[] attributes =
        (DescriptionAttribute[])fi.GetCustomAttributes(
        typeof(DescriptionAttribute),
        false);

    if (attributes != null &&
        attributes.Length > 0)
        return attributes[0].Description;
    else
        return value.ToString();
}

これにより、私は次のようなコードを書くことができます。

var myEnumDescriptions = from MyEnum n in Enum.GetValues(typeof(MyEnum))
                         select new { ID = (int)n, Name = Enumerations.GetEnumDescription(n) };

Enumの値(例:1)がわかっていれば、どうしたらよいですか?説明を取得する方法を教えてください。つまり、GetDescriptionメソッドに渡すために整数を "Enum値"に変換するにはどうすればよいですか?

338
davekaro
int value = 1;
string description = Enumerations.GetEnumDescription((MyEnum)value);

C#のenumのデフォルトの基本データ型はintです。これをキャストするだけで済みます。

326

更新

制約のないメロディライブラリはもうメンテナンスされていません。 Enums.NET を支持して、サポートは中止されました。

Enums.NETではあなたが使用するでしょう:

string description = ((MyEnum)value).AsString(EnumFormat.Description);

元の投稿

私はこれを一般的でタイプセーフな方法で 制約のないMelody - で実装しました。

string description = Enums.GetDescription((MyEnum)value);

この:

  • 値が本当に列挙型の値であることを保証します(一般的な型制約付き)。
  • あなたの現在の解決策でボクシングを避けます
  • すべての説明でリフレクションを使用しないように、すべての説明をキャッシュします。
  • 説明から値を解析する機能など、他にもたくさんの方法があります。

基本的な答えはintからMyEnumへのキャストだけであることを私は理解していますが、もしあなたがたくさんのenum作業をしているのなら、Unconstrained Melodyを使うことを考える価値があります:)

81
Jon Skeet

私は一般的な拡張方法で受け入れられた答えからコードをまとめました、それでそれはあらゆる種類のオブジェクトのために使われることができました:

public static string DescriptionAttr<T>(this T source)
{
    FieldInfo fi = source.GetType().GetField(source.ToString());

    DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(
        typeof(DescriptionAttribute), false);

    if (attributes != null && attributes.Length > 0) return attributes[0].Description;
    else return source.ToString();
}

元の投稿のような列挙型、またはプロパティがDescription属性で装飾されている他のクラスを使用すると、コードは次のように消費されます。

string enumDesc = MyEnum.HereIsAnother.DescriptionAttr();
string classDesc = myInstance.SomeProperty.DescriptionAttr();
70
Irish

これを使いやすくするために、私は一般的な拡張子を書きました:

public static string ToDescription<TEnum>(this TEnum EnumValue) where TEnum : struct
{
    return Enumerations.GetEnumDescription((Enum)(object)((TEnum)EnumValue));
}

今書くことができます:

        MyEnum my = MyEnum.HereIsAnother;
        string description = my.ToDescription();
        System.Diagnostics.Debug.Print(description);

注:上記の「列挙型」を自分のクラス名に置き換えてください。

28
David

これを一般的な方法で簡単に行うことはできません。整数を特定のタイプの列挙型にのみ変換できます。 Nicholasが示したように、これは1種類のenumだけに関心がある場合は簡単なキャストですが、さまざまな種類のenumを処理できる汎用メソッドを作成したい場合は、状況が少し複雑になります。次のような方法でメソッドが欲しいのです。

public static string GetEnumDescription<TEnum>(int value)
{
  return GetEnumDescription((Enum)((TEnum)value));  // error!
}

しかしこれは、 "intはTEnumに変換できない"というコンパイラエラーになります(そしてこれを回避すれば、 "TEnumはEnumに変換できません")。そのため、オブジェクトにキャストを挿入してコンパイラをだます必要があります。

public static string GetEnumDescription<TEnum>(int value)
{
  return GetEnumDescription((Enum)(object)((TEnum)(object)value));  // ugly, but works
}

これを呼び出して、手元にある列挙型の種類に関係なく説明を取得できます。

GetEnumDescription<MyEnum>(1);
GetEnumDescription<YourEnum>(2);
7
itowlson