103 votes

Méthode d'extension et objet dynamique

Je vais résumer mon problème dans l'extrait de code suivant.

List<int> list = new List<int>() { 5, 56, 2, 4, 63, 2 };
Console.WriteLine(list.First());

Le code ci-dessus fonctionne bien.

Maintenant, j'ai essayé ce qui suit

dynamic dList = list;
 Console.WriteLine(dList.First());

mais je reçois une RuntimeBinderException, pourquoi ?

0 votes

Cette question semble être un double de celle posée il y a seulement 4 jours. stackoverflow.com/questions/5270782/

0 votes

@jbtule La différence est que la this est dynamique ici, mais si vous atterrissez ici, vous devriez probablement regarder cette question aussi.

0 votes

149voto

Eric Lippert Points 300275

Pour développer la réponse de Jon, la raison pour laquelle cela ne fonctionne pas est que dans le code régulier, non dynamique, les méthodes d'extension fonctionnent en effectuant une recherche complète de toutes les classes connues par le compilateur pour une classe statique qui a une méthode d'extension qui correspond. La recherche se fait dans l'ordre en fonction de l'imbrication des espaces de noms et des classes disponibles. using dans chaque espace de nom.

Cela signifie que pour que l'invocation d'une méthode d'extension dynamique soit résolue correctement, le DLR doit savoir d'une manière ou d'une autre au moment de l'exécution ce que toutes les imbrications d'espaces de noms et using Les directives ont été dans votre code source . Nous ne disposons pas d'un mécanisme pratique pour encoder toutes ces informations dans le site d'appel. Nous avons envisagé d'inventer un tel mécanisme, mais nous avons décidé que le coût était trop élevé et que les risques liés au calendrier étaient trop importants pour en valoir la peine.

0 votes

Merci beaucoup pour l'explication.

3 votes

Une telle fonctionnalité est-elle en préparation ? Il s'agirait certainement d'un changement radical ; les appels qui génèrent actuellement des RunTimeBinderExceptions se mettraient soudainement à fonctionner lors de la recompilation des sources. De plus, y aurait-il des risques de sécurité associés à la mise en œuvre d'une telle fonctionnalité ?

5 votes

@ani : Avons-nous l'intention de mettre en œuvre cette fonctionnalité ? Non. Y a-t-il des risques pour la sécurité ? Je n'en ai pas connaissance ; quel type de risque de sécurité aviez-vous en tête ? Commencez par dire qui est l'attaquant et quelle menace il représente pour l'utilisateur.

141voto

Jon Skeet Points 692016

Pour développer la réponse de Stecya... les méthodes d'extension ne sont pas supportées par le typage dynamique. sous la forme de méthodes d'extension c'est-à-dire qu'elles sont appelées comme s'il s'agissait de méthodes d'instance. Cependant, cela fonctionnera :

dynamic dList = list;
Console.WriteLine(Enumerable.First(dList));

Bien sûr, cela peut être utile ou non. Si vous pouviez donner plus d'informations sur la raison et la manière dont vous essayez d'utiliser le typage dynamique, nous pourrions peut-être vous aider davantage.

0 votes

Est-ce que vous avez écrit un article sur ce sujet, où utiliser ou ne pas utiliser l'objet dynamique ?

19 votes

@geek : Personnellement, ma règle d'or est d'utiliser seulement dynamic lorsque vous en avez vraiment besoin... En fait, si vous accédez aux membres par réflexion, c'est un signe important. D'un autre côté, je suis un typer statique pur et dur - d'autres peuvent suggérer des politiques moins pessimistes :)

2 votes

Il serait peut-être plus lisible de renvoyer vers le type connu, mais cela fonctionne : Console.WriteLine(((List<int>)dList).First()) ; Ou Console.WriteLine((dList as List<int>).First()) ;.

20voto

Stecya Points 12073

Parce que First() n'est pas une méthode de List . Il est défini dans Linq Extension comme IEnumerable<>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X