2009-02-06 9 views

Antwort

7

Ecma 335 gibt an (aber verlangt nicht), dass Compiler die Präfixe get_/set_ verwenden (Kapitel 22.28). Ich kenne keine Sprache, die diese Empfehlung bricht. Macht es einfach:

public static PropertyInfo GetPropFromMethod(Type t, MethodInfo method) { 
    if (!method.IsSpecialName) return null; 
    return t.GetProperty(method.Name.Substring(4), 
    BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); 
} 
+2

Aus dem informativen Text muss CLS-konform sein, aber keine gültige IL sein. –

+1

Ich würde nicht empfehlen, so zu gehen. Ich empfehle, alle Eigenschaften zu überprüfen. String-Muster Konvention - nicht robust. –

+1

Ich würde gerne ein Gegenbeispiel sehen. –

17

Nun, die Methode hinter einem Getter und Setter sind "echte" Methoden.

Die Rückverfolgung auf eine Eigenschaft - das Muster (Rückgabe vs take 1 arg) wird helfen, es einzuengen - aber Sie müssen GetGetMethod/GetSetMethod auf jedem die Eigenschaft zu finden.

Sie könnten wahrscheinlich versuchen Sie die Name (weniger bekommen __/set__) - aber das fühlt sich spröde. Hier ist die längere Version (keine Verwendung von Name):

static PropertyInfo GetProperty(MethodInfo method) 
{ 
    bool takesArg = method.GetParameters().Length == 1; 
    bool hasReturn = method.ReturnType != typeof(void); 
    if (takesArg == hasReturn) return null; 
    if (takesArg) 
    { 
     return method.DeclaringType.GetProperties() 
      .Where(prop => prop.GetSetMethod() == method).FirstOrDefault(); 
    } 
    else 
    { 
     return method.DeclaringType.GetProperties() 
      .Where(prop => prop.GetGetMethod() == method).FirstOrDefault(); 
    } 
} 
+0

+1 für die Problemumgehung, bevorzugen Sie immer noch die 'name.StartsWith ("get_"/"set_")' obwohl. – arul

+0

hmm ... vielleicht für C# -Code, zumindest ... sie sind in 17.2.7.1 von ECMA 335 erwähnt - aber wird das auf andere Sprachen angewendet? Ich überprüfe ECMA 334 ... –

+0

Sicher ist, überprüfen Sie Abschnitt 17.2.7.1. Für eine Eigenschaft P vom Typ T sind folgende Signaturen reserviert: void set_P (T-Wert); Beide Signaturen sind reserviert, auch wenn die Eigenschaft schreibgeschützt oder schreibgeschützt ist. – arul

5

Blick in MethodBase.IsSpecialName. Methoden, die nicht klar sichtbar sein sollten, wie z. B. Eigenschaftenzugriffsobjekte, Ereignisabonnementmethoden und Operatorüberladungen, verwenden dieses Flag.

Nach meinem Wissen gibt es keine Möglichkeit, die PropertyInfo zu finden, ohne die Eigenschaften zu durchlaufen und die Methoden zu vergleichen.

+0

Gemäß MS können Sie nicht garantieren, dass das Flag IsSpecialName festgelegt wird: http://connect.microsoft.com/VisualStudio/feedback/details/108302/for-property-accresters-get-set-isspecialname-false –

+0

IsSpecialName scheint jedoch zu funktionieren. Ich hoffe, dass MS dies geändert hat, weil es besser ist, die Flagge zu überprüfen, anstatt zu überlegen, welche Sprachmerkmale als (möglicherweise nicht markierte) spezielle Methoden implementiert sind. –

5

ich wirklich möchte dies als Kommentar verlassen, aber ich kann nicht, da mein rep ist nicht hoch genug :(

Theres ein Fehler in Marc GRA Code: Wenn es einen Indexer es wird null zurück, auch wenn ein Elternteil Eigenschaft vorhanden es ist schön zu haben, dass schnell scheitern, aber ich denke, dass wir nur so tun können, wenn es weder einen Rückgabewert oder einen Parameter hat.

[Pure] 
    public static PropertyInfo GetParentProperty(this MethodInfo method) 
    { 
     if (method == null) throw new ArgumentNullException("method"); 
     var takesArg = method.GetParameters().Length == 1; 
     var hasReturn = method.ReturnType != typeof(void); 
     if (!(takesArg || hasReturn)) return null; 

     if (takesArg && !hasReturn) 
     { 
      return method.DeclaringType.GetProperties().FirstOrDefault(prop => prop.GetSetMethod() == method); 
     } 
     else 
     { 
      return method.DeclaringType.GetProperties().FirstOrDefault(prop => prop.GetGetMethod() == method); 
     } 
    } 
-1

Der Trick spielen mit ist BindingFlags.DeclaredOnly und IsSpecialName