2008-08-20 16 views
15

これはおそらく一例として最もよく示されています。私はインスタンスからそれらの属性を取得したい誰かが、enum値のカスタム属性に素早くアクセスする方法を知っていますか?

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 
} 

が、列挙型を変換するために、厄介なようです値を文字列(名前を反映)に変換します。

もっと良い方法がありますか?

+0

'Enum.GetName()'と比較しましたか? –

答えて

9

これはおそらく最も簡単な方法です。

より迅速な方法は、動的メソッドとILGeneratorを使用してILコードを静的に放出することです。私はこれをGetPropertyInfoに使用しただけですが、なぜCustomAttributeInfoを発行できなかったのかわかりません。サンプルコードは、プロパティから

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

をゲッターを発するようにするために

私は一般的に反射が限り、あなたは、動的にメソッドを呼び出さないよう、非常に迅速であることがわかりました。
enumの属性を読み取っているだけなので、実際のパフォーマンスヒットなしでうまくいくはずです。

一般的に、理解しやすいようにしてください。数ミリ秒を得るためにこれを工夫することは価値がないかもしれません。

関連する問題