IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

[Reflexion] donner un type à T


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif
    Avatar de stailer
    Homme Profil pro
    Architecte technique
    Inscrit en
    Mars 2003
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 144
    Billets dans le blog
    3
    Par défaut [Reflexion] donner un type à T
    Bonjour,

    Je suis en train de développer une librairie qui utilise à un certain moment ce type de code (très schématique) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    List<trucs> monObject = new List<trucs>();
    TransformeVar<T>(monObject);
    Je voudrais rendre une autre partie de mon code plus générique, je ne vais pas rentrer dans les détails, mais en gros : j'aimerais passer en paramètre : T

    Je voudrais rendre le code ci-dessus et ne pas être obligé de typer T en dur dans le code, j'aimerais que ce soit dynamique.

    J'ai fait quelques essais avec de la réflexion mais rien à faire... quelqu'un aurait il déjà fait ça ? ou aurait une idée ?

    En vous remerciant pour votre aide,

  2. #2
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    Je suis désolé mais je ne comprends pas la question. Et je ne pense pas être le seul.

    Dans ton appel de TransformeVar, T est-il supposé représenté le type source (celui de monObject), ou un type de destination après une conversion ? Dans le premier cas il n'est pas nécessaire d'ajouter "<T>", dans le second je ne vois pas comment le programme pourrait lire dans ton esprit la conversion que tu souhaites faire.

    Bref, j'imagine que tu voulais dire tout autre chose.

  3. #3
    Membre extrêmement actif
    Avatar de stailer
    Homme Profil pro
    Architecte technique
    Inscrit en
    Mars 2003
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 144
    Billets dans le blog
    3
    Par défaut
    Je me doutais que j'étais pas clair.

    Ok, donc voici clairement le truc :

    Aujourd'hui j'ai ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    public void GetClients(string JsonResult)
    { }
    Dans la librairie que je suis en train de développer, donc autant le dire : une suite de classe permettant de développer facilement du Silverlight avec PHP, j'ai à un moment donné ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     SrvClientReturnObject obj = JsonConvert.DeserializeObject<SrvClientReturnObject>(e.Result);
     
                        Type myTypeObj = ClasseAppellante.GetType();
                        MethodInfo myMethodInfo = myTypeObj.GetMethod(obj.MethodName);
     
     
                        myMethodInfo.Invoke(launcher, new object[] { obj.CustomResult });
    C'est pas mal... Dans ma méthode qui reçoit la chaine Json je peux faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    public void GetClients(string JsonResult)
    { 
    List<clients> MesClients = JsonConvert.DeserializeObject<List<clients>>(JsonResult);
    }
    Ca fonctionne bien mais je voudrais aller plus loin et carrément avoir ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public void GetClients(List<clients> mesClients)
    { 
    }
    Pour cela il faut que ma méthode qui utilise la réflexion puisse utiliser ce type en paramètre

    Alors j'ai essayé le code suivant mais qui ne marche pas bien évidemment :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     SrvClientReturnObject obj = JsonConvert.DeserializeObject<SrvClientReturnObject>(e.Result);
    
                        Type myTypeObj = ClasseAppellante.GetType();
                        MethodInfo myMethodInfo = myTypeObj.GetMethod(obj.MethodName);
    
    
    ParameterInfo info = myMethodInfo.GetParameters()[0];
    
     var objResult= JsonConvert.DeserializeObject<  info.ParameterType >(obj.CustomResult )
    
    
    
                        myMethodInfo.Invoke(launcher, new object[] { objResult });
    J'ai essayé différentes méthodes trouvées sur le net pour faire du cast dynamiquement mais rien n'y fait.

    Grâce à ce que j'ai développé j'arrive à une archi intéressante qui me permet de fonctionner à peu près comme du WCF.. Mais si je pouvais directement caster ce serait un peu la cerise sur le gâteau

  4. #4
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    En somme, tu souhaites pouvoir définir une méthode "GetClients(List<Client> clients)" et l'appeler en fournissant en argument une chaîne de caractères ?

    Tout dépend de qui doit appeler la méthode : l'appelant sera t-il un membre de la même assembly ou bien étranger à celle-ci ? En fonction de cette réponse, on peut bâtir une solution exploitant la réécriture d'assembly (via Cecil ou PostSharp par exemple) et/ou le typage dynamique (avec ou sans adaptateur).


    EDIT : Oups, faitgué, moi. Pour reprendre ton code qui ne fonctionne pas...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    //  var objResult= JsonConvert.DeserializeObject<  info.ParameterType >(obj.CustomResult );
    var deserializeMethodDefinition = typeof(JsonConvertObject).GetMethod("DeserializeObject");  // JsonConvert.DeserializeObject<>
    var deserializeMethod = deserializeMethodDefinition.MakeGenericMethod(info.ParameterType);   // JsonConvert.DeserializeObject<T>
    var objResult = deserializeMethod.Invoke(null, new object[] { obj.CustomResult });

  5. #5
    Membre extrêmement actif
    Avatar de stailer
    Homme Profil pro
    Architecte technique
    Inscrit en
    Mars 2003
    Messages
    1 144
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 144
    Billets dans le blog
    3
    Par défaut
    Je pense qu'avec ton "MakeGenericMethod" on est pas loin..

    En fait j'ai essayé ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Type myTypeObj = launcher.GetType();
                        MethodInfo myMethodInfo = myTypeObj.GetMethod(obj.MethodName);
     
    ParameterInfo info = myMethodInfo.GetParameters()[0];
     
    var ob = Activator.CreateInstance(info.ParameterType);
     
    var monReturn = JsonConvert.DeserializeAnonymousType(obj.CustomResult.ToString(), ob  );
    Qui ne marche pas....

    Alors que bien sûr ceci fonctionne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Type myTypeObj = launcher.GetType();
                        MethodInfo myMethodInfo = myTypeObj.GetMethod(obj.MethodName);
     
    ParameterInfo info = myMethodInfo.GetParameters()[0];
     
    // fonctionne pas
    //var ob = Activator.CreateInstance(info.ParameterType);
     
    // fonctionne
    var ob = new List<clients>();
     
    var monReturn = JsonConvert.DeserializeAnonymousType(obj.CustomResult.ToString(), ob  );
    Ton code part sur la généricité de "JsonConvert" ou je me trompe ?

    En fait je suis pas loin : sauf que le Activator ne me donne pas le bon type (j'ai une exception qui me le dit) ! alors que le paramètre est bien du bon type.. C'est la ou ça coince

  6. #6
    Membre Expert Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Par défaut
    C'est étrange, Activator fonctionne en principe très bien avec les types génériques, tu es certain que info.ParameterType est bien du type "List<Client>" ?
    Sinon, quelle exception et à quel endroit ?

    A part ça, concernant le code que j'ai donné, il faut distinguer les "définitions de méthodes génériques" (MethodInfo.IsGenericMethodDefinition) et les "methodes génériques" (MethodInfo.IsGenericMethod). Quand tu définis JsonTruc.Convert<T> dans JsonTruc, tu écris une définition. Quant tu l'invoques avec un paramètre "JsonTruc.Convert<String>" tu invoques en fait une méthode générique bâtie depuis la définition.

    Mon code fait exactement cela :il récupère la définition, demande la construction d'une méthode générique avec le paramètre spécifié et l'invoque.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. importance de donner le bon type
    Par Lorenzo77 dans le forum C#
    Réponses: 5
    Dernier message: 21/08/2008, 16h01
  2. [Forms10g] Donner Parametre type text item Procedure
    Par sterix92 dans le forum Forms
    Réponses: 6
    Dernier message: 20/05/2007, 14h48
  3. Réponses: 5
    Dernier message: 29/09/2006, 18h17
  4. [c#][Reflexion] Obtenir le type d'un generic
    Par shwin dans le forum Windows Forms
    Réponses: 12
    Dernier message: 03/08/2006, 17h34
  5. reflexion et type de retour des méthodes
    Par money mark dans le forum Langage
    Réponses: 2
    Dernier message: 09/04/2006, 19h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo