que enum clase c# .net reflection enums attributes

clase - enum c# string



¿Alguien sabe una manera rápida de llegar a los atributos personalizados en un valor enum? (2)

En general, creo que el reflejo es bastante rápido siempre que no invoca dinámicamente métodos.
Ya que solo está leyendo los Atributos de una enumeración, su enfoque debería funcionar perfectamente sin ningún golpe de rendimiento real.

Y recuerde que generalmente debe tratar de mantener las cosas simples de entender. Sobre la ingeniería esto solo para ganar unos pocos minutos puede no valer la pena.

Probablemente esto se muestre mejor con un ejemplo. Tengo una enumeración con atributos:

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, }

Quiero llegar a esos atributos desde una instancia:

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 }

Como esto está usando la reflexión, espero cierta lentitud, pero parece complicado convertir el valor de la enumeración en una cadena (que refleja el nombre) cuando ya tengo una instancia de la misma.

¿Alguien tiene una mejor manera?


Esta es probablemente la forma más fácil.

Una manera más rápida sería emitir de forma estática el código IL utilizando Dynamic Method e ILGenerator. Aunque solo he usado esto para GetPropertyInfo, pero no puedo ver por qué no pudo emitir CustomAttributeInfo también.

Por ejemplo, código para emitir un getter desde una propiedad

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; }