2017-12-19 5 views
0

私は列挙型の値についてStringValue属性を持っているので、私はそれぞれの値に説明を付けることができます:enum値属性のIEnumerable <string>を取得する方法はありますか

public class StringValueAttribute : Attribute 
{ 
    public string Value { get; private set; } 

    public StringValueAttribute(string value) 
    { 
     Value = value; 
    } 
} 

そして、それは私がそれを使用する方法です:

enum Group 
{ 
    [StringValue("Computer Science")] 
    ComputerScience, 

    [StringValue("Software Engineering")] 
    SoftwareEngineering, 

    // ... additional values follow. 
} 

私が取得する方法を持っていますA私がenum(列挙型そのものではなく、値)を取得する別の方法を持っていると思います

public static string GetStringValue(Enum value) 
{ 
    Type type = value.GetType(); 
    FieldInfo fieldInfo = type.GetField(type.ToString()); 
    StringValueAttribute[] attributes = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[]; 

    string stringValue = null; 
    if (attributes.Length > 0) 
    { 
     stringValue = attributes[0].Value; 
    } 

    return stringValue; 
} 

StringValueは、列挙型の値を与えられましたndはGetStringValueメソッドを使用してIEnumerableを取得します。私はそれを達成する方法がわかりません。どのようにこのような方法ができますか?


編集:この質問はHow to get C# Enum description from value?の複製ではありません。列挙型の属性値を取得する方法は分かっていますが、実際には正確にそれを行う方法で質問をしています。私の質問は、enumのすべての属性を列挙する方法です。

+0

は、あなたが 'GetStringValues ()'一般的な方法をしたいわけ? – dbc

+1

独自のカスタム属性ではなく、既存の 'DescriptionAttribute'を使用することができます。 Enumer.GetValues(typeof(EnumType))。キャスト().Select(/ *あなたのメソッド* /)を呼び出します。 –

+0

@dbc - それと同じようなものです。しかし、[ここ](https://stackoverflow.com/a/27101267/1925272)は、このようなメソッドを一般化しないことが推奨されています。 – Sipo

答えて

2

これを実行する最も簡単な方法は、汎用的ですそのすべての値:

public static class EnumExtensions 
{ 
    public static IEnumerable<string> GetStringValues<TEnum>() where TEnum : struct, IConvertible, IComparable, IFormattable 
    { 
     return Enum.GetValues(typeof(TEnum)) 
      .Cast<Enum>() 
      .Select(e => e.GetStringValue()) 
      .ToList(); 
    } 

    public static IEnumerable<string> GetStringValuesOfType(Enum value) 
    { 
     return Enum.GetValues(value.GetType()) 
      .Cast<Enum>() 
      .Select(e => e.GetStringValue()) 
      .ToList(); 
    } 

    public static string GetStringValue(this Enum value) 
    { 
     Type type = value.GetType(); 
     FieldInfo fieldInfo = type.GetField(value.ToString()); 
     StringValueAttribute[] attributes = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[]; 

     string stringValue = null; 
     if (attributes.Length > 0) 
     { 
      stringValue = attributes[0].Value; 
     } 

     return stringValue; 
    } 
} 

注:

  • C#にはwhere TEnum : Enumという制約はありません。 TEnumstruct, IConvertible, IComparable, IFormattableに制限することは、、ほとんどはです。言われ、SLaksによってEnum type constraints in C#からthis answerに示されenum制約を適用する狡猾なトリックがあること

  • 。 (私はそれが本当に非常に狡猾だからしかし、この答えでそれを使用していませんでした。)

  • @ EdPlunkettさんのコメントで述べたように、あなたがその特定の着信enum値に対応するフィールドを取得しているので、あなたがtype.GetField()value.ToString()を渡す必要があります。

サンプルfiddle

+0

完全に動作します。ありがとう。 – Sipo

1

これは動作するはずです:あなたは常に、その後のためStringValue値を返す、あなたの特定のEnumのインスタンスに渡し、そのタイプを得ることができるものの

static void Main(string[] args) 
{ 
    foreach (var item in GetStringNames<Group>()) 
    { 
     Console.WriteLine(item); 
    } 
} 
public static string GetStringValue(Enum value) 
{ 
    Type type = value.GetType(); 
    FieldInfo fieldInfo = type.GetField(value.ToString()); 
    StringValueAttribute[] attributes = fieldInfo.GetCustomAttributes(typeof(StringValueAttribute), false) as StringValueAttribute[]; 

    string stringValue = null; 
    if (attributes.Length > 0) 
    { 
     stringValue = attributes[0].Value; 
    } 

    return stringValue; 
} 

public static IEnumerable<string> GetStringNames<T>() 
{ 
    var type = typeof(T); 

    if (type.IsEnum == false) 
    { 
     throw new ArgumentException("T must be an Enum type"); 
    } 

    var values = type.GetEnumValues(); 

    foreach (var item in values) 
    { 
     yield return GetStringValue((Enum)item); 
    } 
} 
+0

ありがとう!私は@ dbcの答えを選択しました。なぜなら、それは私のプログラムには適していたからです。しかし、あなたの答えがうまくいくように思えます。 – Sipo

関連する問題