2008-08-20 32 views
15

Bu, muhtemelen en iyi örneklerle gösterilmektedir. Ben örneğinden bu özelliklerle almak istiyorumHerkes enum değerinde özel özelliklere ulaşmanın hızlı bir yolunu biliyor mu?

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

: Ben özelliklere sahip bir enum var bazı yavaşlık bekliyoruz yansıma kullanıyor bu gibi

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 
} 

, ancak enum dönüştürmek için dağınık görünüyor Zaten bir örneğim olduğunda bir dizeye (adı yansıtan) değer.

Daha iyi bir yolu olan var mı?

+0

Enum.GetName() 'ile karşılaştırdınız mı? –

cevap

9

Bu muhtemelen en kolay yoldur. Dinamik Yöntemi ve ILGenerator kullanarak IL kodunu statik olarak yaymanın daha hızlı bir yolu olacaktır. Her ne kadar bunu yalnızca GetPropertyInfo için kullandım, ancak neden CustomAttributeInfo yayımlayamadığını da göremiyorum. dinamik yöntemleri çağırmak yok gibi örnek kodu için

sürece

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

Genellikle yansıma oldukça hızlı olmasını bulmak bir özelliğinden bir alıcı yayacak şekilde.
Sadece enum'un Niteliklerini okuyor olduğunuzdan, yaklaşımınız herhangi bir gerçek performans isabeti olmadan gayet iyi çalışmalıdır.

Ve unutmayın ki, genellikle basit şeyleri anlamaya çalışın. Bu sadece birkaç ms kazanmak için mühendislik üzerinde buna değmez olabilir.