Alguien sabe una manera rápida de obtener los atributos personalizados en un valor de enumeración?

StackOverflow https://stackoverflow.com/questions/17772

Pregunta

Esta es probablemente la mejor muestra con un ejemplo.Tengo un enum con los atributos de:

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 los atributos de 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 este es el uso de la reflexión espero alguna lentitud, pero parece complicado para convertir el valor de enumeración a una cadena (que refleja el nombre) cuando ya tengo una instancia de ella.

¿Alguien tiene una mejor forma?

¿Fue útil?

Solución

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

Una forma más rápida sería Estáticamente Emiten el código IL utilizando el Método Dinámico y ILGenerator.Aunque sólo lo he usado esto para GetPropertyInfo, pero no puede ver por qué no pudo emitir CustomAttributeInfo así.

Por ejemplo, el código para emitir un captador de 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;
}

Otros consejos

Yo por lo general encontrar reflexión a ser bastante rápida como siempre que no dinámicamente invocar métodos.
Puesto que usted está leyendo los Atributos de una enumeración, su enfoque debe de funcionar bien sin impacto en el rendimiento.

Y recuerde que por lo general usted debe tratar de mantener las cosas simples de entender.Más de la ingeniería de esto sólo para ganar unos ms podría no valer la pena.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top