هل يعرف أحد طريقة سريعة للوصول إلى السمات المخصصة لقيمة التعداد؟

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

سؤال

ربما يكون من الأفضل إظهار ذلك بمثال.لدي تعداد مع السمات:

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
}

نظرًا لأن هذا يستخدم الانعكاس، أتوقع بعض البطء، ولكن يبدو أنه من الصعب تحويل قيمة التعداد إلى سلسلة (والتي تعكس الاسم) عندما يكون لدي مثيل لها بالفعل.

هل لدى أي شخص طريقة أفضل؟

هل كانت مفيدة؟

المحلول

ربما تكون هذه هي الطريقة الأسهل.

تتمثل الطريقة الأسرع في إصدار كود IL بشكل ثابت باستخدام الطريقة الديناميكية وILGenerator.على الرغم من أنني استخدمت هذا فقط لـ 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;
}

نصائح أخرى

أجد عمومًا أن الانعكاس سريع جدًا طالما أنك لا تستدعي الأساليب ديناميكيًا.
نظرًا لأنك تقرأ للتو سمات التعداد، فيجب أن يعمل أسلوبك بشكل جيد دون أي نتيجة حقيقية للأداء.

وتذكر أنه يجب عليك عمومًا أن تحاول إبقاء الأمور بسيطة بحيث يسهل فهمها.الإفراط في هندسة هذا فقط للحصول على بضع مللي ثانية قد لا يستحق كل هذا العناء.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top