begin process at 2010 02 10 10:26:53
  Trouver un code source :
 
dans
 
Accueil > 

Tutoriels

 > 

.NET

 > Programmation dynamique dans le .Net

Programmation dynamique dans le .Net


 Information sur le tutoriel

Note :
Aucune note

 Description

Courte présentation (une petite approche) des techniques qui permettent la programmation dynamique : réflexion, génériques, arborescence d'expression, LINQ, création d'IL, compilation dynamique, DLR.
Bonne lecture...

Tutorial

Programmation dynamique


Source en vidéo : http://www.microsoft.com/france/vision/mstechdays09/Webcast.aspx?eID=490a4112-6a60-403d-9e86-9ada349529b1


- Par réflexion

Pour rappelle : vous pouvez retourner le type (System.Type) d’un objet avec sa méthode GetType() (héritage de object) et d’un type avec le mot clef typeof. Partant de là il est possible de connaître toutes les composantes de l’objet et de son type et d’utiliser ses méthodes -hors discussion sur les permissions-. Il existe d’autres mots clefs (is, as) et classes pour compléter l’utilisation. On peut ainsi ‘parcourir’ et utiliser tout son module…


Ex : utilisation d'une méthode connue d'une classe 'inconnue' contenant cette méthode

    public void Add<T1, T2>(T1 liste, T2 item) {

        liste.GetType().GetMethod("Add").Invoke(liste, new object[] { item }); }


- Avec le type dynamic (C#4)

C'est un nouveau type du prochain framework 4 permettant de passer la compilation sans vérification (donc pas d'IntelliSense). Le type réel sera défini et vérifié dynamiquement par réflexion.

Ex : dynamic objet = ..un objet, par exemple un List<string>..; objet.Add("string1");

De même, avec ScriptObject. Ex : ScriptObject liste = ..un objet, par exemple un List<string>..; liste.Invoke("Add", "string1");


- Par utilisation d'un DynamicProxy

Il simule dynamiquement un objet (pouvant être distant) en interceptant les appels sur cet objet. Pour l'utiliser il faut dériver de la classe RealProxy (classe abstract de System.Runtime.Remoting.Proxies) et implémenter la méthode Invoke qui sera appelée pour chaque appel sur l'objet derrière le proxy.


- Avec les génériques

Les délégués génériques :

    - Func<..TypesParamètres.., TypeDeRetour> eq. à delegate TypeDeRetour Func(..TypesParamètres..);

    - Action<..TypesParamètres..> eq. à delegate void Func(..TypesParamètres..);

Les classes génériques, ex :

    public void CréationListGen<T>(T objet) {

        var typeListeGen = typeof(List<>);

        // Le CLR va définir dynamiquement le type générique (ex string). Equivaut ici à List<T>

        var typeListeDeStrings = typeListeGen.MakeGenericType(typeof(T));

        // Création d'une liste, juste pour l'exemple

        var listeDeStrings = typeListeDeStrings.GetConstructor(Type.EmptyTypes).Invoke(null);

        // Ajout d'un élément, juste pour l'exemple

        listeDeStrings.GetType().GetMethod("Add").Invoke(listeDeStrings, new object[] { objet }); }


- Les arbres d'expressions

La classe Expression contient des méthodes de fabrique statiques qui créent des nœuds d'arborescence d'expression. L'espace de noms System.Linq.Expressions fournit une API pour générer des arborescences d'expression manuellement. On peut également fournir un délégué qui sera -si possible- décomposé en arbre. Cet arbre peut être parcouru, modifié et compilé dynamiquement. Ex :

    // Expression lambda décomposée sous forme d'arbre.

    Expression<Func<double, double>> expr = x => Math.Pow(x, 2) + 3 * x + 5;

    // L'arbre est compilé en code qui pourra être exécuté par appel de delExpr.

    Func<double, double> delExpr = expr.Compile();

    double val = delExpr(5.0);


- Avec LINQ

En effet les requêtes (notamment avec Linq to SQL) sont repoussées et exécutées uniquement au moment de leur utilisation. Pour ce faire Linq utilise abondamment les génériques, les expressions lambda et les arborescences d'expression.

Note : on peut - pour améliorer les performances - compiler ses requêtes. Ex :

    System.Data.Linq.CompiledQuery.Compile((source, type de paramètres optionnels) => requête linq);


- Par création et exécution dynamique de code par construction en IL

Dans System.Reflection.Emit plusieurs classes (DynamicMethod, etc) permettent de construire du code IL (Intermediate Language) qui peut être interprété dynamiqument.

Ex :

    // Type des paramètres

    Type[] helloArgs = { typeof(string), typeof(int) };

    // Méthode crée dynamiquement

    DynamicMethod hello = new DynamicMethod("Hello", // son nom

     typeof(int), // type du retour

     helloArgs, // type des paramètres

     typeof(string).Module);

    // On prépare l'injection du code : sortie sur la Console...

    Type[] writeStringArgs = { typeof(string) };

    MethodInfo writeString = typeof(Console).GetMethod("WriteLine", writeStringArgs);

    ILGenerator il = hello.GetILGenerator(256); // Injection du code...

    il.Emit(OpCodes.Ldarg_0);

    il.EmitCall(OpCodes.Call, writeString, null);

    il.Emit(OpCodes.Ldarg_1);

    il.Emit(OpCodes.Ret);

    // Infos sur les paramètres ; pour le debugging

    ParameterBuilder parameter1 = hello.DefineParameter(1, ParameterAttributes.In, "message");

    ParameterBuilder parameter2 = hello.DefineParameter(2, ParameterAttributes.In, "valueToReturn");

    // Un delegate pour exécuter la méthode dynamique.

    HelloDelegate hi = (HelloDelegate)hello.CreateDelegate(typeof(HelloDelegate)); // avec delegate int HelloDelegate(string msg, int ret);

    int retval = hi("\r\nHello, World!", 42);


- Par envoi d'instruction sous forme de string au compilateur

Les classes dans l'espace Microsoft.CSharp (et System.CodeDom.Compiler) permettent de compiler (en mémoire ou dans un fichier) et le cas échéant d'éxécuter du code contenu dans un string.

Ex :

    CSharpCodeProvider provider = new CSharpCodeProvider();

    ICodeCompiler compileur = provider.CreateCompiler();

    CompilerResults cr = provider.CompileAssemblyFromSource(new CompilerParameters(),

        @"using System; public class Eval{public static double MultPar2(double x) { return x * 2; } }");// Le code.

    if (cr.Errors.Count > 0) throw new Exception("Erreur sur le code dynamique.");

    var ret = cr.CompiledAssembly.GetType("Eval").GetMethod("MultPar2").Invoke(null, new object[] { 50 });// Retourne 100.


- Par utilisation des langages dynamiques (avec la DLR) :

La Dynamic Language Runtime est une surcouche du .NET Framework 3.5 permettant de faciliter la création de langages dynamiques pour .NET. Ce langage peut être un langage intégré à une application ou plus largement l'implémentation d'un nouveau langage pour .NET à l'image d'IronPython ou de IronRuby. Son utilisation est facilitée avec Siverlight notamment avec le Javascript et/ou Python.


Commentaires

Aucun commentaire pour le moment.

 Ajouter un commentaire




Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2010
LMMJVSD
1234567
891011121314
15161718192021
22232425262728

Consulter la suite du CalendriCode

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,062 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales