2008-08-20 33 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

我通常发现反映相当迅速发出吸气只要你不动态调用方法。
由于您只是阅读枚举的属性,因此您的方法应该可以正常工作,而不会有任何实际性能问题。

请记住,您通常应该尽量让事情简单易懂。过度工程这只是为了获得几个毫秒可能不值得。