Wie überprüfe ich, ob ein Objekt eine bestimmte Methode / Eigenschaft hat?


155

Verwenden Sie vielleicht ein dynamisches Muster? Sie können jede Methode / Eigenschaft mit dem dynamischen Schlüsselwort aufrufen, oder? Wie kann ich überprüfen, ob die Methode vorhanden ist, bevor ich beispielsweise myDynamicObject.DoStuff () aufrufe?


Was ist der Typ von myDynamicObject ? Ist es eine Klasse abgeleitet von DynamicObject?
Cheng Chen

etwas mit dem dynamischen Schlüsselwort deklariert
Louis Rhys

Antworten:


224

Sie könnten so etwas schreiben:

public static bool HasMethod(this object objectToCheck, string methodName)
{
    var type = objectToCheck.GetType();
    return type.GetMethod(methodName) != null;
} 

Bearbeiten: Sie können sogar eine Erweiterungsmethode ausführen und diese so verwenden

myObject.HasMethod("SomeMethod");

GetType () gibt den Laufzeittyp zurück? (dh kein Objekt?)
Louis Rhys

2
Ja, GetType () gibt den laufenden Typ zurück, während typeof () ein Objekt zurückgeben würde.
Julien

1
Laut den Dokumenten gibt GetType () "den genauen Laufzeittyp der aktuellen Instanz" zurück.
Zup

Außerdem müsste die Erweiterungsmethode statisch sein.
Fraser

9
Ich schreibe lieber: objectToCheck.GetType (). GetMethod (methodName)! = Null
efirat

85

über Reflexion

 var property = object.GetType().GetProperty("YourProperty")
 property.SetValue(object,some_value,null);

Ähnliches gilt für Methoden


Nett. Sie können die GetMethod auch in einer Schleife ausführen, um die entsprechende definierte Eigenschaft abzurufen.
Jnr

Nützlich zum Durchlaufen verknüpfter Listen von UI-Steuerelementen und deren Eltern
Chicowitz

In GetType()gibt es Methode wie GetProperties(). Es wird ein Array von zurückgegeben PropertyInfo. Aber wie kann ich die GetProperties()Methode anwenden?
Yogesh Patel

43

Es ist eine alte Frage, aber ich bin gerade darauf gestoßen. Type.GetMethod(string name)löst eine AmbiguousMatchException aus, wenn es mehr als eine Methode mit diesem Namen gibt, sodass wir diesen Fall besser behandeln können

public static bool HasMethod(this object objectToCheck, string methodName)
{
    try
    {
        var type = objectToCheck.GetType();
        return type.GetMethod(methodName) != null;
    }
    catch(AmbiguousMatchException)
    {
        // ambiguous means there is more than one result,
        // which means: a method with that name does exist
        return true;
    }
} 

18

Wäre es nicht besser, dafür keine dynamischen Typen zu verwenden und Ihre Klasse eine Schnittstelle implementieren zu lassen? Anschließend können Sie zur Laufzeit überprüfen, ob ein Objekt diese Schnittstelle implementiert und somit über die erwartete Methode (oder Eigenschaft) verfügt.

public interface IMyInterface
{
   void Somemethod();
}


IMyInterface x = anyObject as IMyInterface;
if( x != null )
{
   x.Somemethod();
}

Ich denke, das ist der einzig richtige Weg.

Sie beziehen sich auf die Ententypisierung, was in Szenarien nützlich ist, in denen Sie bereits wissen, dass das Objekt über die Methode verfügt, der Compiler dies jedoch nicht überprüfen kann. Dies ist beispielsweise in COM-Interop-Szenarien nützlich. (siehe diesen Artikel)

Wenn Sie zum Beispiel Ententypisierung mit Reflexion kombinieren möchten, dann verfehlen Sie meiner Meinung nach das Ziel der Ententypisierung.


2
Was ist, wenn das Objekt ein vom .NET Framework bereitgestelltes Objekt sein kann und ich es nicht für die Implementierung deklarieren kann?
Louis Rhys

Was ist das Problem ? Sie können auf die gleiche Weise überprüfen, ob das 'Objekt' ein solches Objekt ist, das vom .NET Framework bereitgestellt wird
Frederik Gheysels

Sie möchten beispielsweise überprüfen, ob ein Objekt eine "Hinzufügen" -Methode enthält. Und das Objekt kann eine Liste <int> oder eine andere Klasse sein, die keine IEnumerable ist
Louis Rhys

3
Vielleicht sollten Sie sich ein Skript für ein Adobe-Produkt mit COM ansehen. Der gleiche Funktionsaufruf kann völlig unterschiedliche COM-Objekte zurückgeben, und nach (Adobe) Design ist das Objekt ihr einziger gemeinsamer Vorfahr. Außerdem: Dies ist ein alltägliches Muster in so ziemlich jeder modernen dynamischen Skriptsprache (Python, Javascript, VB-Skript, PHP, Lua ... ich könnte weiter und weiter machen). Es ist kein Fehler, es ist ein Feature.
Tim Keating

5
Es ist ein Geruch, aber es wurde von Microsoft erstellt. Schauen Sie sich WebControls wie Button, LinkButton usw. an. Beide implementieren die OnClientClick-Eigenschaft, ListControl und Panel jedoch nicht. OnClientClick ist in einer Schnittstelle nicht definiert, daher ist Reflektion die einzige Option.
HammerIp
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.