Canard essais de type avec C# 4 pour les objets dynamiques
Je suis désireux d'avoir un simple duck-typing exemple en C# en utilisant des objets dynamiques. Il me semble, qu'un objet dynamique devrait avoir HasValue/HasProperty/HasMethod méthodes avec une seule chaîne de caractère en paramètre le nom de la valeur, la propriété ou la méthode que vous recherchez avant d'essayer d'exécuter contre elle. J'essaie d'éviter les blocs try/catch, et un approfondissement de la réflexion, si possible. Il semble juste être une pratique courante pour de canard en tapant dans la dynamique des langues (JS, Ruby, Python, etc) qui est à l'essai pour une propriété/méthode avant d'essayer de l'utiliser, puis revenir à un défaut ou à lancer une exception contrôlée. L'exemple ci-dessous est en gros ce que je veux accomplir.
Si les méthodes décrites ci-dessus n'existent pas, quelqu'un aurait-il premade les méthodes d'extension pour la dynamique qui va le faire?
Exemple: En JavaScript, je peux le tester pour une méthode sur un objet assez facilement.
//JavaScript
function quack(duck) {
if (duck && typeof duck.quack === "function") {
return duck.quack();
}
return null; //nothing to return, not a duck
}
Comment pourrais-je faire la même chose en C#?
//C# 4
dynamic Quack(dynamic duck)
{
//how do I test that the duck is not null,
//and has a quack method?
//if it doesn't quack, return null
}
- Juste une remarque pour ceux qui cherchent... ExpandoObject (pas sûr d'autres) met en œuvre IDictionary<string, object> de sorte que vous pouvez tester avec var myDynamicAsDictionary = myDyn comme IDictionary<string, object> ensuite de tester la valeur null, et .HasKey()
- double possible de dynamic, Comment tester si une propriété est disponible
- la mienne a 2 jours plus tôt que l'un est lié à... je pensais juste qu'il pourrait être possible de créer une telle vérification des méthodes de type générique signatures...
Duck.HasFunc<TRet, T1>(string name)
comme un exemple de signature... je n'utilisez pas le C# à ce niveau, mais ce serait intéressant. - Je le vois. Parfois, il est ok pour fermer une question qui est plus âgé si la nouvelle question a reçu plus d'attention. Mais je vois votre point de vue.
Vous devez vous connecter pour publier un commentaire.
Essayez ceci:
Ou ce (utilise seulement dynamique):
dynamic
à tous, c'est juste la norme de la réflexion...Microsoft.CSharp.RuntimeBinder
n'est pas utilisé par défaut, au moins dans mon installation de LINQPad et Visual Studio 2010. Vous devrez ajouter manuellement unusing ...
ou qualifierRuntimeBinderException
pleinement que dansMicrosoft.CSharp.RuntimeBinder.RuntimeBinderException
pour la deuxième solutino de travail.Si vous avez le contrôle sur tous les types d'objet qui vous permettra d'utiliser de façon dynamique, une autre option serait de les forcer à hériter d'une sous-classe de la
DynamicObject
classe qui est adapté pour ne pas échouer lorsqu'une méthode qui n'existe pas est invoquée:Un rapide et sale version devrait ressembler à ceci:
Vous pouvez ensuite effectuer les opérations suivantes:
Et votre sortie serait:
Edit: je tiens à noter que c'est la partie émergée de l'iceberg si vous êtes en mesure d'utiliser cette approche et de construire sur
DynamicObject
. Vous pouvez écrire des méthodes commebool HasMember(string memberName)
si vous le souhaité.Mise en œuvre de la HasProperty méthode pour chaque idynamicmetaobjectprovider fournie par SANS jeter RuntimeBinderException.
http://code.google.com/p/impromptu-interface/ Semble être une belle Interface mappeur pour les objets dynamiques... C'est un peu plus de travail que ce que j'espérais, mais semble être le plus propre de la mise en œuvre des exemples présentés... en Gardant Simon réponse comme correcte, puisque c'est toujours la plus proche de ce que je voulais, mais l'Impromptu de méthodes d'interface sont vraiment sympa.
Le chemin le plus court serait de l'appeler, et de gérer l'exception, si la méthode n'existe pas. Je viens de Python où cette méthode est courante dans de canard-typage, mais je ne sais pas si il est largement utilisé en C#4...
Je n'ai pas testé moi-même puisque je n'ai pas de CR 2010 sur ma machine