任何人都知道一个快速的方法来获得一个枚举值的自定义属性?
这可能是最好的例子。 我有一个枚举属性:
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
}
因为这是使用反射我期望一些缓慢,但是当我已经有一个它的实例时,将枚举值转换为一个字符串(它反映了名字)似乎很麻烦。
有没有人有更好的方法?
这可能是最简单的方法。
更快的方法是使用Dynamic Method和ILGenerator静态发射IL代码。 虽然我只用它来GetPropertyInfo,但不明白你为什么不能发出CustomAttributeInfo。
例如从属性发出一个getter的代码
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;
}
只要不动态调用方法,我一般会发现反射速度非常快。
既然你只是阅读一个枚举的属性,你的方法应该很好,没有任何实际的性能影响。
请记住,你通常应该尽量让事情简单易懂。 过度工程这只是为了获得几个毫秒可能不值得。
链接地址: http://www.djcxy.com/p/38109.html上一篇: Anyone know a quick way to get to custom attributes on an enum value?