Comment vérifier si un objet a une certaine méthode / propriété?

155

Vous utilisez peut-être un modèle dynamique? Vous pouvez appeler n'importe quelle méthode / propriété en utilisant le mot-clé dynamic, non? Comment vérifier si la méthode existe avant d'appeler myDynamicObject.DoStuff (), par exemple?

Louis Rhys
la source
Quel est le type de myDynamicObject ? Est-ce une classe dérivée de DynamicObject?
Cheng Chen
quelque chose déclaré avec le mot
Louis Rhys

Réponses:

224

Vous pourriez écrire quelque chose comme ça:

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

Edit: vous pouvez même faire une méthode d'extension et l'utiliser comme ça

myObject.HasMethod("SomeMethod");
Julien
la source
GetType () retournera le type d'exécution? (c'est-à-dire pas d'objection?)
Louis Rhys
2
oui, GetType () renvoie le type en cours tandis que typeof () renverrait object.
Julien
1
Selon la documentation, GetType () retournera "Le type d'exécution exact de l'instance actuelle".
tzup
En outre, la méthode d'extension devrait être statique.
Fraser
9
Je préfère écrire: objectToCheck.GetType (). GetMethod (methodName)! = Null
efirat
85

par réflexion

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

Il en va de même pour les méthodes

Stecya
la source
Agréable. Vous pouvez également effectuer GetMethod dans une boucle pour obtenir la propriété définie appropriée.
Jnr
Utile pour parcourir les listes chaînées de contrôles de l'interface utilisateur et de leurs parents
Chicowitz
Il GetType()y a une méthode comme GetProperties(). Il renvoie un tableau de PropertyInfo. Mais comment utiliser la GetProperties()méthode?
Yogesh Patel
43

C'est une vieille question, mais je viens de la rencontrer. Type.GetMethod(string name)lèvera une AmbiguousMatchException s'il y a plus d'une méthode avec ce nom, donc nous ferons mieux de gérer ce cas

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;
    }
} 
esskar
la source
18

Ne serait-il pas préférable de ne pas utiliser de types dynamiques pour cela et de laisser votre classe implémenter une interface. Ensuite, vous pouvez vérifier au moment de l'exécution si un objet implémente cette interface et, par conséquent, possède la méthode (ou propriété) attendue.

public interface IMyInterface
{
   void Somemethod();
}


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

Je pense que c'est la seule manière correcte.

La chose à laquelle vous faites référence est le typage canard, ce qui est utile dans les scénarios où vous savez déjà que l'objet a la méthode, mais le compilateur ne peut pas vérifier cela. Ceci est utile dans les scénarios d'interopérabilité COM par exemple. (consultez cet article)

Si vous voulez combiner la frappe de canard avec la réflexion, par exemple, je pense que vous manquez l'objectif de la frappe de canard.

Frederik Gheysels
la source
2
Que faire si l'objet peut être un objet fourni par le framework .NET et que je ne peux pas le déclarer pour implémenter quoi que ce soit?
Louis Rhys
Quel est le problème ? Vous pouvez vérifier si `` l'objet '' est un tel objet, fourni par le framework .NET de la même manière
Frederik Gheysels
par exemple, vous voulez vérifier s'il existe une méthode "Add" dans un objet. Et l'objet peut être un List <int>, ou une autre classe qui n'est pas un IEnumerable
Louis Rhys
3
Vous devriez peut-être jeter un œil à la création de scripts pour un produit Adobe avec COM. Le même appel de fonction peut renvoyer des objets COM entièrement différents, et par la conception (d'Adobe), leur seul ancêtre commun est l'objet. Aussi: c'est un modèle courant dans à peu près n'importe quel langage de script dynamique moderne (Python, Javascript, script VB, PHP, Lua ... je pourrais continuer encore et encore). Ce n'est pas un bug, c'est une fonctionnalité.
Tim Keating
5
C'est une odeur mais elle a été créée par Microsoft. Regardez les WebControls tels que Button, LinkButton, etc. Ils implémentent tous deux la propriété OnClientClick mais, disons, ListControl et Panel ne le font pas. OnClientClick n'est pas défini dans une interface, la réflexion est donc la seule option.
HammerIp