7
votes

Y a-t-il un c # équivalent à `répond_to de Ruby?`?

J'écris un wrapper simple sur "canard" A objet dynamique contre une interface connue: xxx

ceci fonctionne bien si le dynamique < / Code> L'objet peut répondre à la barre Signature. Mais si cela ne peut pas cela ne casse que lorsque j'appelle bar . Je préférerais si cela pourrait échouer plus vite, c'est-à-dire avec la validation de l'argument lors de la construction du chargeur wrapper de Duckfoo . Quelque chose comme ceci: xxx

in ruby ​​il y a un réponse_to? méthode pouvant être utilisé pour tester si un objet "a" une méthode donnée. Existe-t-il un moyen de tester qu'avec des objets dynamiques au C # 4?

(Je suis conscient que même avec cette vérification, l'appel de la barre pourrait échouer plus tard parce que la nature dynamique du canard Le permet d'arrêter de répondre aux méthodes plus tard.)


0 commentaires

3 Réponses :


4
votes

Vous pouvez vérifier les méthodes disponibles sur l'objet enveloppé à l'aide de la réflexion, au temps de construction.

Il suffit d'appeler Type.getMethods () sur l'interface et le type étant passé, et assurez-vous que les méthodes appropriées existent.


EDIT:

Comme suggéré par itowlson , il existe une option pour la gestion des types dynamiques. Si vous vérifiez l'existence de l'interface IdynnamicMetaObjectProvider sur l'objet transduit, vous pouvez ensuite appeler idynnamicmetaObjectProvider.getMetaObject () . GetDynamicMemberNames () et utilisez ces informations.

Si l'interface n'existe pas, vous pouvez simplement revenir à Type.getMethods ().

Ceci devrait également gérer les types "dynamiques", également.


9 commentaires

Que se passe-t-il lorsque vous faites duck.gettype () si canard est déclaré comme canard dynamique ? Quel type retour-t-il?


Si l'objet dynamique est un objet .NET, vous obtenez le type de l'objet.


Je ne pense pas que vous puissiez faire une réflexion comme celle-là sur des objets dynamiques ... peut-être s'ils sont des objets CLR réguliers, vous pouvez, mais vous ne pouvez pas avec des objets venant de IronRuby, par exemple ...


Cela fonctionnera pour les objets CLR. Si vous traitez avec un type provenant d'une langue complètement dynamique, la langue peut avoir ses propres mécanismes pour cela. Cependant, il est difficile (très délicat) de fournir une sécurité de type sur, par définition, des objets non essuyés. Si vous traitez d'un objet vraiment non typ, vous devez utiliser les mécanismes de cette langue pour le dépêcher de type, ou laissez-le comme une vérification d'exécution.


@DTB: Comme le dit Maximilian, s'il s'agit d'un objet CLR régulier traité comme dynamique, vous obtenez le type de l'objet. Mais si vient d'une langue dynamique, ce sera quelque chose du long des lignes de ironrubydynamicObject ou IronPythondynamicObject (NB: J'ai fait ces noms, je ne connais pas les noms actuels )


Ouais je sais. Si c'est un objet dynamique, cependant, je le laisserais personnellement dynamique. Il n'ya aucun moyen de savoir qu'une méthode ne sera pas supprimée entre le temps que vous construisez et le temps que vous appelez, par exemple. Dans ce cas, Runtime échoue comme le plus sens.


Vous pouvez combiner les getMethods statiques () avec un test pour idynnamicmetaObjectProvider et un appel à idynnamicmetaObjectProvider.getMetaObject (). GetDynamicMembern Ames ().


Notez qu'il existe des mécanismes normalisés pour des objets dynamiques dans .NET 4 (E.G. expandoObject ), il n'est donc pas toujours spécifique de la langue même pour des objets dynamiques réels.


@Pavel: Bon appel. Totalement oublié ça! @Ilwlson: C'est plus comme ce que je voulais.



0
votes

Utilisez la réflexion pour vérifier les méthodes: xxx


1 commentaires

Cela fonctionne, mais uniquement avec des objets CLR réguliers. Des objets vraiment dynamiques pourraient ne pas avoir de méthode de barre et toujours répondre à l'appel.



1
votes

Je ne connais pas de manière définitive de vérifier si l'objet fournit une méthode spécifique. Bien sûr, vous pouvez utiliser la réflexion, mais cela ne fonctionne que si l'objet est un objet .NET. Si vous êtes sûr que c'est que c'est que, comme déjà dit, aucun problème, appelez simplement gettype () sur l'objet et vérifiez avec getMethod ().

D'autre part, comme vous l'avez dit, même un chèque à ce stade ne garantit pas que l'appel à la méthode réussira plus tard, alors je pense que le chèque est inutile. Laissez simplement l'appel échouer quand il le fait réellement. Il pourrait également s'agir de votre chèque indiquant que l'objet ne fournit pas de méthode spécifique, mais plus tard, lorsque vous l'appelleriez, cela le fait.


0 commentaires