Come verificare se un oggetto ha un determinato metodo / proprietà?


155

Usi il modello dinamico forse? Puoi chiamare qualsiasi metodo / proprietà usando la parola chiave dinamica, giusto? Come verificare se il metodo esiste prima di chiamare myDynamicObject.DoStuff (), ad esempio?


Qual è il tipo di myDynamicObject ? È una classe derivata DynamicObject?
Cheng Chen,

qualcosa dichiarato con la parola chiave dinamica
Louis Rhys,

Risposte:


224

Potresti scrivere qualcosa del genere:

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

Modifica: puoi persino fare un metodo di estensione e usarlo in questo modo

myObject.HasMethod("SomeMethod");

GetType () restituirà il tipo di runtime? (cioè non obiettare?)
Louis Rhys,

2
Sì, GetType () restituisce il tipo in esecuzione mentre typeof () restituisce oggetto.
Julien,

1
Secondo i documenti GetType () restituirà "Il tipo di runtime esatto dell'istanza corrente".
TZUP

Inoltre, il metodo di estensione dovrebbe essere statico.
Fraser,

9
Preferisco scrivere: objectToCheck.GetType (). GetMethod (methodName)! = Null
efirat

85

tramite la riflessione

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

Simile è per i metodi


Bello. È inoltre possibile eseguire GetMethod in un ciclo per ottenere la proprietà definita appropriata.
Jnr

Utile per scorrere gli elenchi collegati di controlli dell'interfaccia utente e dei loro genitori
Chicowitz,

In GetType()c'è metodo come GetProperties(). Sta tornando array di PropertyInfo. Ma come posso usare il GetProperties()metodo?
Yogesh Patel,

43

È una vecchia domanda, ma mi sono appena imbattuto. Type.GetMethod(string name)genererà AmbiguousMatchException se esiste più di un metodo con quel nome, quindi è meglio gestire quel caso

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

Non sarebbe meglio non usare alcun tipo dinamico per questo, e lasciare che la tua classe implementasse un'interfaccia. Quindi, è possibile verificare in fase di esecuzione se un oggetto implementa quell'interfaccia e quindi ha il metodo (o proprietà) previsto.

public interface IMyInterface
{
   void Somemethod();
}


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

Penso che questo sia l'unico modo corretto.

La cosa a cui ti riferisci è la tipizzazione anatra, che è utile in scenari in cui sai già che l'oggetto ha il metodo, ma il compilatore non può verificarlo. Ciò è utile, ad esempio, negli scenari di interoperabilità COM. (controlla questo articolo)

Se ad esempio si desidera combinare la tipizzazione con l'anatra con la riflessione, penso che manchi l'obiettivo di scrivere con l'anatra.


2
cosa succede se l'oggetto può essere un oggetto fornito dal framework .NET e non posso dichiararlo per implementare qualcosa?
Louis Rhys,

Qual è il problema ? Puoi verificare se l '"oggetto" è un tale oggetto, fornito dal framework .NET allo stesso modo
Frederik Gheysels,

ad esempio, si desidera verificare se esiste un metodo "Aggiungi" in un oggetto. E l'oggetto può essere un Elenco <int>, o qualche altra classe che non è un IEnumerable
Louis Rhys,

3
Forse dovresti dare un'occhiata allo scripting di un prodotto Adobe con COM. La stessa chiamata di funzione può restituire oggetti COM completamente diversi e, in base alla progettazione (di Adobe), il loro unico antenato comune è object. Inoltre: questo è un modello comune in quasi tutti i moderni linguaggi di scripting dinamico (Python, Javascript, VB script, PHP, Lua ... Potrei andare avanti all'infinito). Non è un bug, è una funzionalità.
Tim Keating,

5
È un odore ma è stato creato da Microsoft. Guarda WebControls come Button, LinkButton, ecc. Entrambi implementano la proprietà OnClientClick ma, diciamo, ListControl e Panel no. OnClientClick non è definito in un'interfaccia, quindi la riflessione è l'unica opzione.
HammerIp
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.