2008-08-20 64 views
15

這可能是最好的例子。我有一個屬性的枚舉:任何人都知道快速獲取枚舉值的自定義屬性的方法嗎?

public enum MyEnum { 

    [CustomInfo("This is a custom attrib")] 
    None = 0, 

    [CustomInfo("This is another attrib")] 
    ValueA, 

    [CustomInfo("This has an extra flag", AllowSomething = true)] 
    ValueB, 
} 

我想從一個實例的屬性:

public CustomInfoAttribute GetInfo(MyEnum enumInput) { 

    Type typeOfEnum = enumInput.GetType(); //this will be typeof(MyEnum) 

    //here is the problem, GetField takes a string 
    // the .ToString() on enums is very slow 
    FieldInfo fi = typeOfEnum.GetField(enumInput.ToString()); 

    //get the attribute from the field 
    return fi.GetCustomAttributes(typeof(CustomInfoAttribute ), false). 
     FirstOrDefault()  //Linq method to get first or null 
     as CustomInfoAttribute; //use as operator to convert 
} 

由於這是使用反射我期待一些緩慢,但它似乎雜亂枚舉轉換當我已經擁有它的一個實例的時候,這個值就是一個字符串(它反映了名字)。

有沒有人有更好的方法?

+0

你和Enum.GetName()比較了嗎? – 2008-08-20 12:41:06

回答

9

這可能是最簡單的方法。

更快的方法是使用Dynamic Method和ILGenerator靜態發射IL代碼。雖然我只用它來GetPropertyInfo,但不明白你爲什麼不能發出CustomAttributeInfo。

例如代碼從屬性

public delegate object FastPropertyGetHandler(object target);  

private static void EmitBoxIfNeeded(ILGenerator ilGenerator, System.Type type) 
{ 
    if (type.IsValueType) 
    { 
     ilGenerator.Emit(OpCodes.Box, type); 
    } 
} 

public static FastPropertyGetHandler GetPropertyGetter(PropertyInfo propInfo) 
{ 
    // generates a dynamic method to generate a FastPropertyGetHandler delegate 
    DynamicMethod dynamicMethod = 
     new DynamicMethod(
      string.Empty, 
      typeof (object), 
      new Type[] { typeof (object) }, 
      propInfo.DeclaringType.Module); 

    ILGenerator ilGenerator = dynamicMethod.GetILGenerator(); 
    // loads the object into the stack 
    ilGenerator.Emit(OpCodes.Ldarg_0); 
    // calls the getter 
    ilGenerator.EmitCall(OpCodes.Callvirt, propInfo.GetGetMethod(), null); 
    // creates code for handling the return value 
    EmitBoxIfNeeded(ilGenerator, propInfo.PropertyType); 
    // returns the value to the caller 
    ilGenerator.Emit(OpCodes.Ret); 
    // converts the DynamicMethod to a FastPropertyGetHandler delegate 
    // to get the property 
    FastPropertyGetHandler getter = 
     (FastPropertyGetHandler) 
     dynamicMethod.CreateDelegate(typeof(FastPropertyGetHandler)); 


    return getter; 
} 
7

我通常發現反映相當迅速發出吸氣只要你不動態調用方法。
由於您只是閱讀枚舉的屬性,因此您的方法應該可以正常工作,而不會有任何實際性能問題。

請記住,您通常應該儘量讓事情簡單易懂。過度工程這只是爲了獲得幾個毫秒可能不值得。