Astuces DotNet (Sébastien Courtois)

16/04/2010

[Nouveautés C# .NET 4] Introduction au C# dynamique

Filed under: .NET, C# 4, Débutant — Étiquettes : , , , , , , — sebastiencourtois @ 09:42

Une des nouveautés qui a fait couler beaucoup d’encre est l’ajout des types dynamiques à .NET 4. Cela venait d’un besoin pour des langages “dynamiques” tel que le Javascript, Python ou encore le Ruby de pouvoir être facilement interopérable avec les langages plus traditionnels comme le C# ou le VB. Microsoft a ainsi rajouter une couche au framework : La DLR (Dynamic Langage Runtime) ainsi qu’un langage supplémentaire tirant entièrement parti de la dlr : le F#.

  • Le principe de fonctionnement

Le but des types dynamiques de pouvoir appeler des méthodes/propriétés d’un objet et que la résolution (le lien entre le code appelant et le code appelé) ne se fasse pas au moment de la compilation mais que cette résolution se fasse à l’exécution.

dlr Comme on peut le voir ci dessus, les types .NET sont résolus au moyen d’un “object binder” qui n’est autre qu’un code utilisant la réflexion. Pour les langages dynamiques, chacun a sa propre méthode de résolution.

Il est à noter quel la DLR s’appuie sur la CLR. Les langages C#/VB peuvent ainsi choisir d’utiliser le couple DLR/CLR ou uniquement la CLR (comme avant). Lorsque la DLR est utilisé, celle ci retraduit les appels pour qu’il soit exécutable par la CLR.

dlr2

  • Le mot clé dynamic en C#

Afin de décider le type de runtime nous allons utiliser, C# 4 introduit un nouveau mot clé dynamic. Ce mot clé permet d’indiquer que l’instance de l’objet sera interprété par la DLR et non pas par la CLR directement. Cela permet d’appeler n’importe quel méthode/propriété/indexer de la classe sans connaitre son nom et ses paramètres à la compilation.

int a = 0;
dynamic b = a;
b = 1;
//a = 0 , b = 1
List<int> list = new List<int>() { 0, 1, 2, 3, 4, 5 };
dynamic listDynamic = list;
listDynamic.Add(6);
list.Add(7);
//list = {0,1,2,3,4,5,6,7}
//listDynamic = {0,1,2,3,4,5,6,7}

Ce code montre qu’il est possible de convertir tout type (valeur / références) dans des types dynamiques.

dlr3 Le fonctionnement général de la mémoire n’est pas bouleversé par le mot clé dynamique (les types références vont toujours sur le tas, les types valeurs sur la pile). La seule différence réside au niveau de l’object binder qui,dans le cas de types dynamiques, fera la résolution au moment de l’éxécution du programme.

public class Test
{
    public string ValA { get; set; }
    public int ValB;
    public dynamic ValC;

    public void Toto(int a){}
    public string Tata(dynamic b) { return string.Empty; }
}

Concernant le mot clé dynamic, il est aussi possible de l’utiliser dans les définitions des propriétés,les paramètres de méthodes, les types retours, les indexeurs … bref, on peut l’utiliser dans tous les cas.

  • On pouvait faire du dynamique en C# 3.5 ?

Il était possible de réaliser ce type d’opération en .NET 3.5. Voici un exemple de code permettant l’appel de méthode dont on passe le nom en paramètres.

public void CallMethod<T>(T instance, string methodName) where T : class
{
   Type t = instance.GetType();
   MethodInfo mi = t.GetMethod(methodName);
   if (mi == null)
     throw new InvalidOperationException(string.Format("La méthode {0} n'existe pas pour le type {1}", methodName, t.Name));
   mi.Invoke(instance,new object[]{});
}

On remarque que le code reste très complexe pour juste appeler une méthode d’une classe. Microsoft nous a donc maché le travail afin de ne plus à avoir utiliser la reflection dans ce genre de cas.

  • Un grand pouvoir implique de grandes responsabilités

Comme je l’ai dit au début de l’article, cette nouveautés a fait couler beaucoup d’encre. Je suis plutôt contre cette fonctionnalités pour les raisons suivantes :

  1. Lisibilité du code : A l’instar du mot clé var introduit en .NET 3.5, rendre un langage comme C# en partie dynamique va réduire la lisibilité du code car on ne saura plus le type des différentes variables car de nombreux développeurs vont préférer écrire des var/dynamic partout plutôt que typer correctement leurs instances.
  2. Intellisense : Le mot clé dynamic entraine une résolution à l’exécution. Cela veut dire que, au moment de la compilation, on ne dispose d’aucune informations sur la structure des objets que l’on utilise ce qui rend l’écriture du code complexe (une faute de frappe ou de majuscule et on obtient une erreur …. à l’éxécution.)dlr4
  3. Erreur de résolution : Comme expliqué ci-dessus, les fautes de frappes peuvent arriver lorsque l’on code (surtout sans aide de l’intellisense) et on se retrouve avec des erreurs à l’éxécution. Cela introduit un temps supplémentaire car on obtient les erreurs de résolutions après la compilation/exécution. De plus, pour un peu que l’on ne passe pas dans le code où se trouve l’erreur, on ne la voit jamais et c’est l’utilisateur final qui en ait victime.

dlr5

  • Conclusion

L’ajout de la DLR est une fonctionnalité sympathique pour l’interopérabilité entre langages statiques et dynamiques. Cela devrait décupler les possibilités des langages .NET et surement entrainer de nouveaux pattern de développement. Toutefois, à l’instal du mot clé var, il se peut que cela soit au détriment de la qualité/lisibilité du code.

Si vous avez des commentaires/questions sur le sujet, n’hésitez pas à commenter.

3 commentaires »

  1. La grande question que je me pose depuis que la DLR a été dévoilée, c’est : qu’en est-il des performances?

    Manipuler – par exemple – un type référence par le biais du mot-clef dynamic a-t-il un coût particulier? Et si oui, est-il raisonnable ou plombe-t-il fortement les perfs?

    Puisque l’ObjectBinder utilise la reflection, j’aurais tendance à croire que les performances peuvent en être fortement affectées…

    Ce qui m’inquiète aussi c’est que les débutants risquent de coller des dynamic partout, car ce sera un moyen simple (mais dégueulasse) de résoudre des problèmes d’architecture. Et je ne parle même pas de l’ExpandoObject qui permet de créer des types à la volée, façon Javascript.

    Commentaire par François G. — 16/04/2010 @ 17:11

  2. Pour répondre aux diverses questions :
    1°) Performances DLR vs CLR
    Des tests que j’avais réalisé sur les bétas, je trouvais que cela plombais très fortement les performances (surement un post de blog là dessus prochainement avec tests à l’appui). Le seul contexte à mes yeux qui vaut le coup performance/utilité est le cas de l’interop avec un autre langage dynamique. Je n’ai malheureusement pas assez d’expérience dans ce domaine et dynamic vient juste de sortir donc on verra dans les prochaines années ce qu’il en est.

    2°) dynamic/Expando :
    Entièrement d’accord, les débutants vont se ruer dessus (plus sur var que dynamic car les débutants aiment bien l’intellisense). Effectivement ça peut aider à corriger des problèmes d’architecture mais a quel prix🙂.
    ExpandoObject => C# = Javascript/PHP🙂.

    Un domaine que je vais explorer plus en détail est le combat DLR vs MEF dans la réalisation de plug in. Je pense (pour l’avoir beaucoup utilisé) que MEF est plus approprié mais on ne sait jamais.

    Commentaire par sebastiencourtois — 16/04/2010 @ 17:19

  3. A titre personnel :

    Microsoft avait un language dynamique : visual foxpro ils ont stoppés le produit parce que l’on pouvait tout faire avec… même des tests unitaires voir le site foxunits.org puis sont arrivés de nouveau language dynamique Python & Ruby. Et M$ a compris son erreur un peu tard à mon gout.
    Je me forme sur C# et il me faut 2 heures pour faire ce que je faisais en Fox en 5 Minutes. J’ai l’impression de revenir à l’assembleur 8086 ou IBM370.
    Il n’y a pas de mauvais produits de développement seulement de mauvais programmeurs.
    Alors si M$ a mis un peu de dynamique, à titre personnel celà m’arrange. Peut être même qu’il feront un VisualFoxPro.net mais celà relève de l’utopie.
    Pour l’instant je regarde Lianja qui supportent plusieurs language :python, fox, javascript.

    P@trick

    Commentaire par Gilles — 22/02/2012 @ 02:49


RSS feed for comments on this post. TrackBack URI

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

Propulsé par WordPress.com.

%d blogueurs aiment cette page :