Frage

Dies ist wahrscheinlich am besten mit einem Beispiel.Ich habe ein enum mit Parametern:

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

Ich will diese Attribute von Instanz:

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
}

Als diese ist die Verwendung von reflektion ich erwarten, dass einige Langsamkeit, aber es scheint chaotisch zu konvertieren, die enum-Wert in einen string (der Ausdruck der name), wenn ich bereits eine Instanz von es.

Hat jemand einen besseren Weg?

War es hilfreich?

Lösung

Dies ist wahrscheinlich der einfachste Weg.

Ein schneller Weg sein würde, zu Statisch Strahlen der IL-code über Dynamische Methode und ILGenerator.Zwar habe ich nur diese verwendet, um GetPropertyInfo, aber kann nicht sehen, warum Sie konnte nicht emittieren CustomAttributeInfo als gut.

Für den Beispiel-code zu emittieren eine getter-Eigenschaft von einem

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

Andere Tipps

Ich find allgemein Reflexion, ziemlich schnell, wie lange, wie Sie nicht dynamisch aufrufen von Methoden.
Da Sie gerade Lesen der Attribute eines enum, Ihr Ansatz sollte gut funktionieren, ohne wirkliche Leistung Treffer.

Und denken Sie daran, dass Sie grundsätzlich versuchen sollten, die Dinge einfach zu verstehen.Über engineering, nur um zu gewinnen ein paar ms könnte es sich nicht lohnen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top