2016-03-21 29 views
1

によってカスタムで列挙型を取得することができた例がたくさんあります問題は、とattributeTypeすなわちをハードコーディングする必要があり、ここで Get Enum from Description attribute取得列挙型カスタム属性(ジェネリック)

public static class EnumEx 
{ 
    public static T GetValueFromDescription<T>(string description) 
    { 
     var type = typeof(T); 
     if(!type.IsEnum) throw new InvalidOperationException(); 
     foreach(var field in type.GetFields()) 
     { 
      var attribute = Attribute.GetCustomAttribute(field, 
       typeof(DescriptionAttribute)) as DescriptionAttribute; 
      if(attribute != null) 
      { 
       if(attribute.Description == description) 
        return (T)field.GetValue(null); 
      } 
      else 
      { 
       if(field.Name == description) 
        return (T)field.GetValue(null); 
      } 
     } 
     throw new ArgumentException("Not found.", "description"); 
     // or return default(T); 
    } 
} 

しかし、ここのような属性typeof(DescriptionAttribute)) as DescriptionAttribute

この例をGeneric Extensionに変換して、CustomAttributeTypeをハードコードする必要はありません。

+1

でそれを使用しますが、あなたが知っておくべきそれを使用して検索できる入力パラメータの意味と使用方法たとえば、この基準を 'if(attribute.Description == description)'とすることができますが、ジェネリックパラメータを渡したときはどうでしょうか? –

+2

これをどのように翻訳しますか? 'attribute'が' DescriptionAttribute'でないなら 'attribute.Description'ですか? – HimBromBeere

答えて

5

これは、あなたが文字列として値を比較したい任意の属性のために動作します:

あなたは、このように呼ぶだろう
public static TEnum GetValueFromAttribute<TEnum, TAttribute> 
      (string text, Func<TAttribute, string> valueFunc) where TAttribute : Attribute 
{ 
    var type = typeof(TEnum); 
    if(!type.IsEnum) throw new InvalidOperationException(); 
    foreach(var field in type.GetFields()) 
    { 
     var attribute = Attribute.GetCustomAttribute(field, typeof(TAttribute)) as TAttribute; 
     if(attribute != null) 
     { 
      if(valueFunc.Invoke(attribute) == text) 
       return (TEnum)field.GetValue(null); 
     } 
     else 
     { 
      if(field.Name == text) 
       return (TEnum)field.GetValue(null); 
     } 
    } 
    throw new ArgumentException("Not found.", "text"); 
    // or return default(T); 
} 

var value = GetValueFromAttribute<MyEnum, Description>("desc_text", a => a.Description); 
+0

'if(valueFunc(attribute)== text)'型保証を確実にするために 'Invoke'を使わずにfuncを直接呼び出すこともできます。しかし、本当にクールな答え。 – HimBromBeere

+0

@HimBromBeere同じ(Invokeのショートカット) –

0

あなたがいることを、インターフェイスIDescriptionを追加することができますあなたの属性は以下を実装しています:

public interface IDescription 
{ 
    string Description { get; } 
} 

public static class EnumEx 
{ 
    public static T GetValueFromDescription<T, TAttribute>(string description) where TAttribute : Attribute, IDescription 
    { 
     var type = typeof(T); 

     if (!type.IsEnum) throw new InvalidOperationException(); 

     foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Static)) 
     { 
      var attribute = (IDescription)Attribute.GetCustomAttribute(field, typeof(TAttribute)); 

      if (attribute != null) 
      { 
       if (attribute.Description == description) 
       { 
        return (T)field.GetValue(null); 
       } 
      } 
      else 
      { 
       if (field.Name == description) 
       { 
        return (T)field.GetValue(null); 
       } 
      } 
     } 

     throw new ArgumentException("Not found.", "description"); 
     // or return default(T); 
    } 
} 

または完全なベースクラス:

public abstract class BaseDescriptionAttribute : Attribute 
{ 
    public string Description { get; protected set; } 
} 

public static class EnumEx 
{ 
    public static T GetValueFromDescription<T, TAttribute>(string description) where TAttribute : BaseDescriptionAttribute 
    { 
     var type = typeof(T); 

     if (!type.IsEnum) throw new InvalidOperationException(); 

     foreach (var field in type.GetFields(BindingFlags.Public | BindingFlags.Static)) 
     { 
      var attribute = (BaseDescriptionAttribute)Attribute.GetCustomAttribute(field, typeof(TAttribute)); 
0

は、新しいジェネリック型

public static T GetValueFromDescription<T, K>(string description) 

を追加して、あなたはメソッドに他の一般的なパラメータを追加することができますアイデアのようGetCustomerAttribute

var attribute = Attribute.GetCustomAttribute(field, typeof(K)); 
関連する問題