Lacunes de l'utilisation des types dynamiques en C #

14

J'ai récemment étudié davantage les types dynamiques en C #. Avec quelques exemples que j'ai compris une fois que le code est compilé, il n'a pas besoin d'être recompilé à nouveau mais peut être exécuté directement.

Je pense que la flexibilité offerte par le mot-clé pour pouvoir réellement changer le type de données à volonté est un grand avantage .

Question,

Existe-t-il des lacunes spécifiques en dehors des mauvais appels de méthode dynamique qui génèrent des exceptions d'exécution que les développeurs doivent connaître avant de démarrer l'implémentation.

Karthik Sreenivasan
la source
3
En C # 3, j'ai toujours considéré l'utilisation objectou la conversion de type direct comme une odeur de code. Dans presque tous les cas, cela signifiait que moi ou un membre de mon équipe n'avions pas conçu d'interface appropriée pour cette fonctionnalité. Je suppose que si j'utilisais C # 4 maintenant, je ressentirais à peu près la même chose à propos de l'utilisation de dynamictrop. Je pourrais voir le cas si vous rendiez tout dynamique, mais dans ce cas, vous pourriez aussi bien avoir sélectionné une langue typée dynamique en premier lieu. * 8 ')
Mark Booth
@MarkBooth +1 pour la perspective. Est-il alors prudent de dire que l'implémentation principale utilisant C # restera toujours fortement typée malgré l'introduction de types dynamiques dans 4.0
Karthik Sreenivasan
L'utilisation dynamicen C # signifie que vous n'avez pas à abandonner vers IronPython si tout ce dont vous avez besoin est un typage dynamique pour une petite partie de votre code. Pour un évaluateur d'expression, j'ai eu beaucoup de succès en utilisant dynamicpour représenter les opérandes d'une expression et les résultats de l'évaluation.
Ed James
@EdJames - Cela ressemble à une grande utilisation de dynamic, et j'aurais aimé connaître IronPython lorsque je développais avec .Net - cela aurait pu rendre certaines choses que nous essayions de faire beaucoup plus facilement.
Mark Booth
Voir stackoverflow.com/questions/31859016/…
rien n'est nécessaire

Réponses:

16

Le principal inconvénient est que vous jetez l'une des principales propriétés (pas nécessairement des avantages) de C # - qu'il est typé statiquement (et pour la plupart des types sûrs).

Le problème avec le typage dynamique est qu'il cache souvent des bogues qui seraient autrement révélés lors de la compilation. Un tel bogue ne se manifeste alors qu'au moment de l'exécution, ce qui le rend bien sûr beaucoup plus difficile à détecter.

Il y a très peu de raisons à l'OMI d'utiliser le typage dynamique en C #, la principale étant la collaboration avec des langages typés dynamiquement (qui est AFAIK la raison pour laquelle la dynamique a été introduite en premier lieu).

Si vous voulez faire de la programmation entièrement typée dynamiquement, vous devriez regarder un langage qui est conçu pour être dynamique, pas pirater C # pour être dynamique. Vous pouvez utiliser par exemple IronPython si vous souhaitez utiliser des bibliothèques .Net

Matěj Zábský
la source
+1 pour IronPython. Cela signifie que cela pourrait entraîner des problèmes de maintenance à long terme.
Karthik Sreenivasan
6
La grande chose qui dynamicvous donne est la possibilité de monter un objet à son type réel sans aucune sorte de piratage de réflexion. Par exemple, si Base foo = new Derived();et il y avait deux méthodes surchargées Moo(Base x)et Moo(Derived x), alors les Moo(foo)appels Moo(Base x), mais les Moo((dynamic)foo)appels Moo(Derived x). Cela conduit à une implémentation très élégante du modèle Visitor par exemple: code.logos.com/blog/2010/03/… et est en général une technique très puissante.
@TheMouthofaCow Nice, il y a sûrement quelques autres utilisations "légitimes" de la dynamique également, mais celles-ci sont rares et intermédiaires (et vous devez absolument savoir ce que vous faites avant d'essayer quelque chose comme ça).
Matěj Zábský
@TheMouthofaCow Un modèle de conception relativement nouveau (le modèle de visiteur) à noter. Merci.
Karthik Sreenivasan
1
Oui, c'est plutôt cool. Je l'ai trouvé indépendamment la semaine dernière, donc c'était agréable de voir que c'est une idée acceptée qui a été adoptée dans l'arsenal C #.
9

Je ne sais pas quel type de lacunes recherchez-vous, mais si vous voulez en savoir plus sur les fonctionnalités qui fonctionnent avec la frappe statique, mais pas avec dynamic, il y en a peu:

  1. Les méthodes d'extensions ne fonctionnent pas. C'est probablement le plus gros. Si c'est le cas dynamic collection, vous ne pouvez pas utiliser de code comme collection.Distinct(). En effet, les méthodes d'extension disponibles dépendent des espaces de noms usinget le DLR n'a aucun moyen de les connaître.

    Pour contourner ce problème, vous pouvez invoquer la méthode comme si elle était méthode statique normale: Enumerable.Distinct(collection). Ou vous pouvez changer le type de la collection en quelque chose comme IEnumerable<dynamic>.

  2. foreachrequiert IEnumerable. En C # normal, foreachest basé sur un modèle. Autrement dit, il ne nécessite aucune interface spécifique, juste une GetEnumerator()méthode qui renvoie un objet approprié. Si vous utilisez foreachdessus dynamic, l'implémentation de IEnumerableest requise. Mais puisque la raison de ce comportement est que C # 1.0 n'avait pas de génériques, ce "défaut" est à peu près hors de propos.

svick
la source
+1 pour la méthode des extensions. Cela s'applique-t-il également à d'autres opérateurs de requête LINQ comme GroupBy ()?
Karthik Sreenivasan
2
@Karthik: Oui, c'est le cas. Je pense que les méthodes d'extension sont du sucre syntaxique de compilation, d'où le fait qu'elles ne sont pas résolues.
@TheMouthofaCow +1 - Merci pour la clarification.
Karthik Sreenivasan
1
Je suis d'accord avec les méthodes d'extension, c'est-à-dire comment la dynamique ne peut pas comprendre les méthodes d'extension au moment de l'exécution, mais je n'ai pas pu suivre la collection dynamique que vous avez expliquée.
Karthik Sreenivasan
7

Le problème avec les types dynamiques (pas les variables déclarées comme dynamiques) dans .net est qu'ils n'ont pas beaucoup de fonctionnalités disponibles pour les types statiques.

  • il n'y a pas de réflexion (vous pouvez parcourir les membres mais pas grand-chose d'autre)
  • pas de métadonnées (là va votre validation dans les sites de données dynamiques / mvc)
  • absolument aucune vérification au moment de la compilation (aucune faute d'orthographe ne sera détectée)
  • car il s'agit d'une fonctionnalité puissante, les noobs peuvent avoir tendance à en abuser / mal utiliser / mal comprendre
  • le code écrit avec des types dynamiques a tendance à être difficile à maintenir et sacrément difficile à refactoriser
  • en raison de la saisie de canard et d'autres fonctionnalités, les gourous peuvent écrire du code illisible pour quiconque

N'écrivez donc pas de code avec des types dynamiques à moins de savoir ce que vous faites.

linkerro
la source
6

Étant donné qu'il ne dynamics'agit que d'un type, objectil indique les types de valeur.

Cela peut avoir des implications sur les performances, mais étant donné que j'utiliserais de toute façon du typage statique dans du code critique pour les performances, ce n'est probablement pas un problème dans la pratique.

Cette boxe interfère également avec les types de valeurs mutables. Si vous les modifiez avec dynamic, vous ne modifiez que la copie encadrée. Mais comme vous ne devez pas utiliser de types de valeurs mutables en premier lieu, ce n'est pas un gros problème non plus.

CodesInChaos
la source
+1 Je suis tout à fait d'accord. Le typage statique serait la meilleure approche pour le code critique de performance.
Karthik Sreenivasan