La dernière mise à jour majeure du Framework .NET a ajouté un concept ajoutant une couche permettant à C# d’agir comme un langage dynamique. Un langage dynamique permet d’être interprété qu’au moment de son exécution.
Dans les langages dits dynamiques, on retrouve des noms connus comme :
Un language dynamique fait contraste avec un language fortement typé où le code est exécuté au moment de la compilation de celui-ci.
Introduction du type dynamic dans .NET 4.0
Le type dynamic a été introduit à 4.0 afin de court circuiter la validation statique des types. Cet ajout permet de d’écrire du code qui sera résolu une fois seulement qu’il sera exécuté.
Ce nouveau mot clé peut être utilisé à plusieurs sauces. Dans certains cas, son utilisation va sembler assez transparente. Par exemple, les types dynamics sont utilisés assez régulièrement avec ASP.NET MVC avec la mécanique du ViewBag.
Un bel exemple de la différence entre les deux concepts est le code suivant :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var x = 10; | |
var y = "2"; | |
var result = x * y; |
Le code exécuté en javascript va donner le résultat « 20 » car il s’agit de la multiplication de 10 et de 2. Le même code en C# ne passera pas l’étape de la compilation car il n’est pas possible de multiplier un nombre à une chaîne.
Une instance de la classe ExpandoObject vous permet d’avoir accès à un objet totalement dynamique dans lequel vous pouvez y enregistrer l’information que vous y désirez dans des propriétés. Ces propriétés peuvent être aussi être parcourues à l’aide d’une requête.
L’ExpandoObject expose un dictionnaire ayant la signature IDictionary<String, Object>) afin que vous puissiez y retrouver vos propriétés dans une boucle par exemple. Vous pouvez le faire de cette façon :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dynamic expando = new ExpandoObject(); | |
expando.Title = "Ceci est un titre"; | |
expando.Nom = "Paradis"; | |
expando.Prenom = "Pascal"; | |
foreach (var e in (IDictionary<String, Object>) expando) | |
{ | |
Console.WriteLine(e.Value); | |
} |
Ce code va écrire à la console le texte suivant :
Ceci est un titre
Paradis
Pascal
DynamicObject
Considérant l’implémentation vraiment naive d’un objet servant de dictionnaire d’URL :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dynamic urlDictionnary = new UrlDictionnary(); | |
urlDictionnary.HomePage = "http://www.parad.is"; | |
urlDictionnary.About = "https://frenchcoding.wordpress.com/about/"; | |
urlDictionnary.Blog = "https://frenchcoding.wordpress.com"; |
Ce qui est important de savoir avec ce dictionnaire c’est qu’il hérite de la classe DynamicObject. DynamicObject permet à une classe exposant des propriétés ou des fonctionnalités comme un dictionnaire ou une liste d’exposer ses propriétés de façon dynamique.
Dans le cas de cet exemple, il n’est pas question sa savoir quel algorithme de tri dictionnaire d’URL utilise pour trier ses élément mais plus de savoir qu’il est possible d’accéder dynamiquement à ses propriétés.
Pour avoir un minimum de fonctionnalités avec votre classe héritant de DynamicObject, il vous faut réimplémenter les fonctions TryGetMember et TrySetMember. Ces deux réimplémentations vont vous permettre d’avoir les fonctionnalités vous permettant d’accéder et de paramétrer des propriétés dynamiques.
Voici un exemple excessivement simpliste vaguement tiré de MSDN
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class UrlDictionnary : DynamicObject | |
{ | |
Dictionary<string, string> dictionary = new Dictionary<string, string>(); | |
public int Count | |
{ | |
get | |
{ | |
return dictionary.Count; | |
} | |
} | |
public override bool TryGetMember(GetMemberBinder binder, out object result) | |
{ | |
var keyName = binder.Name.ToLower(); | |
if(dictionary.ContainsKey(keyName)) | |
{ | |
result = dictionary[keyName]; | |
return true; | |
} | |
result = null; | |
return false; | |
} | |
public override bool TrySetMember(SetMemberBinder binder, object value) | |
{ | |
dictionary[binder.Name.ToLower()] = (string) value; | |
return true; | |
} | |
} |
2 réflexions sur “C# Dynamics”