2008-09-16 3 views
1

Ich habe einen benutzerdefinierten Handler auf eine Klasse angewendet (mit dem Policy Injection Application Block in Entlib 4) und ich würde gerne wissen, ob die Eingabemethode eine Eigenschaft ist, wenn Invoke aufgerufen wird. Folgendes ist, wie mein Handler aussieht.Was ist der beste Weg zu sagen, ob eine Methode eine Eigenschaft aus der Policy Injection ist?

[ConfigurationElementType(typeof(MyCustomHandlerData))] 
public class MyCustomHandler : ICallHandler 
{ 
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) 
    { 
     if (input.MethodBase.IsPublic && (input.MethodBase.Name.Contains("get_") || input.MethodBase.Name.Contains("set_"))) 
     { 
      Console.WriteLine("MyCustomHandler Invoke called with input of {0}", input.MethodBase.Name); 
     } 
     return getNext().Invoke(input, getNext); 
    } 

    public int Order { get; set; } 
} 

Wie Sie aus meinem Code-Beispiel sehen können, ist der beste Weg, ich so weit ist gedacht habe durch die Methodennamen Parsen. Gibt es dafür keinen besseren Weg?

Antwort

2

Sie auch IsSpecialName überprüfen gilt.

.method public hidebysig specialname static int32 get_ExitCode() cil managed 
.method public hidebysig specialname static void set_ExitCode(int32 'value') cil managed 

Wenn Sie bekommen Lust wollte man konnte: dies wird in einer Eigenschaft (unter anderem)

Am il Ebene die Verfahren ausgesetzt sind wie folgt (unter Verwendung von Environment.ExitCode als Beispiel) wahr sein überprüfen nach den Namen zu extrahieren, die die Eigenschaft aber ehrlich

if (m.IsSpecialName && (m.Attributes & MethodAttributes.HideBySig) != 0)) 

sowie mit get_ oder set_ beginnt zu sein vorhanden ist, dann sollten Sie gut auch für Menschen böse Namen (die hidebysig fälschen ist leicht genug, die IsSpecialName fälschen wäre sehr knifflig)

Nichts ist aber garantiert. Jemand könnte eine Klasse mit einer set_Foo-Methode ausgeben, die genau wie eine echte set-Methode aussieht, aber tatsächlich keine Menge für eine schreibgeschützte Eigenschaft war. Es sei denn, Sie überprüfen, ob die Eigenschaft CanRead/CanWrite auch.

Das erscheint mir als Wahnsinn für Sie, obwohl Sie keine vorsätzliche Umgehung erwarten. Eine einfache Utility/Extension-Methode auf MethodInfo, die diese Logik nicht zu schwer machen würde und die Aufnahme von IsSpecialName würde fast sicher alle Ihre Bedürfnisse abdecken.

0

Sie könnten die IsSpecialName-Eigenschaft überprüfen; das gilt für Property Getter und Setter. Dies gilt jedoch auch für andere spezielle Methoden wie Überlastungen von Operatoren.

0

Einige von Ihnen erwähnten die Eigenschaft "IsSpecialName" des MethodBase-Typs. Es trifft zwar zu, dass der Wert "true" für die Eigenschaft "gets" oder "sets" zurückgibt, aber auch für Operatorüberladungen wie "add_EventName" oder "remove_EventName" wird true zurückgegeben. Daher müssen Sie andere Attribute der MethodBase-Instanz untersuchen, um festzustellen, ob es sich um einen Eigenschaftenaccessor handelt. Wenn Sie lediglich einen Verweis auf eine MethodBase-Instanz haben (was meiner Ansicht nach beim Abfangen von Verhalten im Unity-Framework der Fall ist), gibt es leider keinen echten "sauberen" Weg, um festzustellen, ob es sich um einen Property Setter oder Getter handelt. Der beste Weg, die ich gefunden habe ist wie folgt:

C#:

bool IsPropertySetter(MethodBase methodBase){ 
    return methodBase.IsSpecialName && methodBase.Name.StartsWith("set_"); 
} 

bool IsPropertyGetter(MethodBase methodBase){ 
    return methodBase.IsSpecialName && methodBase.Name.StartsWith("get_"); 
} 

VB:

Private Function IsPropertySetter(methodBase As MethodBase) As Boolean 

     Return methodBase.IsSpecialName AndAlso methodBase.Name.StartsWith("set_") 

End Function 

Private Function IsPropertyGetter(methodBase As MethodBase) As Boolean 

     Return methodBase.IsSpecialName AndAlso methodBase.Name.StartsWith("get_") 

End Function 
0

Es ist ein bisschen spät, aber andere Leute dies zu lesen. Zusätzlich zu IsSpecialName und Überprüfung auf das Präfix set_ (Operatoren haben op_, event subscr./remov.hat add_, remove_) Sie können überprüfen, ob die Methode zu einer der folgenden Eigenschaften-Methoden passt:

bool isProperty = method.ReflectedType.GetProperties().FirstOrDefault(p => 
     p.GetGetMethod().GetHashCode() == method.GetHashCode() 
     || p.GetSetMethod().GetHashCode() == method.GetHashCode())!=null; 
Verwandte Themen