Was ist der beste Weg, wenn eine Methode zu sagen, eine Eigenschaft aus Politik Injection ist?

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

Frage

Ich habe einen benutzerdefinierten Handler bekam auf eine Klasse angewendet (mit der Politik Injection Application Block in EntLib 4), und ich möchte wissen, ob die Eingabemethode eine Eigenschaft ist, wenn Invoke aufgerufen wird. Im Anschluss ist das, was meine Handler aussehen.

[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, die beste Art, wie ich gedacht habe von bisher wird durch die Methodennamen Parsen. Gibt es nicht einen besseren Weg, dies zu tun?

War es hilfreich?

Lösung

Sie können auch überprüfen IsSpecialName wahr ist. dies wahr sein, in einer Eigenschaft (unter anderem)

Am il Ebene werden die Verfahren ausgesetzt, wie folgt (Environment.ExitCode als Beispiel verwendet wird):

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

Wenn Sie wollten Lust bekommen Sie nach dem Extrahieren des Namens überprüfen könnte, daß die Eigenschaft vorhanden ist, aber um ehrlich zu sein

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

sowie beginnt mit get_ oder set_ dann sollten Sie auch für Menschen gut mit fiesen Namen (Fälschen der hidebysig leicht genug ist, wäre sehr schwierig die IsSpecialName Fälschen)

Im Moment ist jedoch gewährleistet. Jemand könnte eine Klasse mit einem set_Foo Verfahren emittiert, das wie eine echte Set-Methode gesucht, aber eigentlich war kein Satz auf einer Nur-Lese-Eigenschaft. Es sei denn, Sie überprüfen, ob die Eigenschaft CanRead / CanWrite auch.

Das erscheint mir als Wahnsinn für Sie wenn Sie nicht bewusste Umgehung erwarten sind. Eine einfache Programm / Erweiterungsmethode auf Method die diese Logik nicht allzu schwer sein würde, und einschließlich IsSpecialName würde mit ziemlicher Sicherheit all Ihren Bedürfnisse abdecken.

Andere Tipps

Sie könnten die IsSpecialName Eigenschaft überprüfen; es wird für Eigenschaft Getter und Setter wahr sein. Allerdings wird es auch wahr für andere spezielle Methoden sein, wie Betreiber Überlastung.

ich mit diesem Applikationsblock nicht vertraut bin, aber davon aus, dass Method Eigenschaft des Typs System.Reflection.MethodBase ist, können Sie einen Blick auf die IsSpecialName Eigenschaft nehmen könnte.

System.Reflection.MethodBase.IsSpecialName auf MSDN

Ein paar von euch erwähnte die „IsSpecialName“ Eigenschaft des Method Typs. Es stimmt zwar, dass die für die Eigenschaft true zurück „wird“ oder „Sets“, wird es auch true zurück für Betreiber Überlastungen wie add_EventName oder remove_EventName. So müssen Sie andere Attribute der Method Instanz prüfen, ob sich eine Eigenschaftenaccessor zu bestimmen. Leider, wenn alles, was Sie haben, ist ein Verweis auf eine Instanz Method (was ich glaube der Fall ist mit Verhalten im Unity Rahmen abfängt) gibt es nicht wirklich „saubere“ Art und Weise, wenn ich eine Eigenschaft Setter oder Getter zu bestimmen. 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

Es ist ein bisschen spät, aber andere Leute dies zu lesen. Neben IsSpecialName und Kontrolle für die set_ Präfix (Betreiber haben op_, Ereignis subscr./remov hat ADD_, remove_.) Sie prüfen, ob Verfahren eine Übereinstimmung mit einem der Eigenschaften Methoden ist wie folgt:

    bool isProperty = method.ReflectedType.GetProperties().FirstOrDefault(p => 
        p.GetGetMethod().GetHashCode() == method.GetHashCode() 
        || p.GetSetMethod().GetHashCode() == method.GetHashCode())!=null;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top