任何人都知道快速获取枚举值的自定义属性的方法吗?
Posted
技术标签:
【中文标题】任何人都知道快速获取枚举值的自定义属性的方法吗?【英文标题】:Anyone know a quick way to get to custom attributes on an enum value? 【发布时间】:2010-09-06 06:37:25 【问题描述】:这可能最好用一个例子来说明。我有一个带有属性的枚举:
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
由于这是使用反射,我预计会有些慢,但是当我已经有枚举值的实例时,将枚举值转换为字符串(反映名称)似乎很麻烦。
谁有更好的办法?
【问题讨论】:
你和Enum.GetName()
比较过吗?
【参考方案1】:
这可能是最简单的方法。
一种更快的方法是使用动态方法和 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;
【讨论】:
【参考方案2】:只要您不动态调用方法,我通常会发现反射非常快。 由于您只是在阅读枚举的属性,因此您的方法应该可以正常工作,而不会影响任何实际性能。
请记住,您通常应该尽量让事情简单易懂。仅仅为了获得几毫秒而过度设计可能并不值得。
【讨论】:
以上是关于任何人都知道快速获取枚举值的自定义属性的方法吗?的主要内容,如果未能解决你的问题,请参考以下文章