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 :

[Réflection] Type Générique "Dynamique"


Sujet :

C#

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    201
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 201
    Points : 196
    Points
    196
    Par défaut [Réflection] Type Générique "Dynamique"
    Bonjour !

    J'ai une question qui peut paraitre un peu complexe (ou pas).
    Je suis actuellement dans la réflection, et je cherche à appeler une Method Généric (method<T>[...]), sur une Propriété Static d'une Class, en ne connaissant que les noms (en string) de chacun.

    Là je ne suis pas sûr de moi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ProviderBase provider = (ProviderBase)typeof(DataRepository).GetProperty(providerName, System.Reflection.BindingFlags.Static).GetValue(null, null);
    En théorie je récupère la Propriété statique de la Class (static) DataRepository.

    Ensuite il me reste à trouver la méthode, là encore il me semble que c'est assez simple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MethodInfo method = provider.GetType().GetMethod(SelectStatement.MethodName);
    Et maintenant... comment je fais pour Invoker cette methode avec mon Type T (dont je n'ai que la représentation en string).

    J'ai bien remarqué 2-3 méthode qui me permettrait d'arriver à mon but, mais sans en saisir vraiment le sens:
    MethodInfo.GetGenericMethodDefinition(), ...


    Si quelqu'un à une piste, ça m'avancerai beaucoup. Ou alors si je pars dans un délire, techniquement irréalisable, je veux bien qu'on me le dise histoire que j'arrête de m'arracher les cheveux

    Merci !

    [EDIT] J'ai trouvé une piste ici: http://msdn.microsoft.com/en-us/library/b8ytshk6.aspx mais je ne suis pas certain du résultats , je vous tiens informé :]

  2. #2
    Membre confirmé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juin 2005
    Messages
    700
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Juin 2005
    Messages : 700
    Points : 488
    Points
    488
    Par défaut
    sujet interressant désolé de ne pouvoir t'aider...

  3. #3
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    Si je comprend bien, tu cherches à faire un truc du genre :

    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    string strGenericType = "System.Collections.ObjectModel.Collection";
    string strGenericTypeParam = "System.String";
    string strMethodToCall = "Add";
    Collection<object> Parameters = new Collection<object>();
    Parameters.Add("Une chaine");
     
    /*
     * Le but ici est donc d'instancier un Collection<string> puis
     * d'appeller la méthode "Add" de cet objet en lui passant les
     * paramètres contenus dans Parameters
     */
     
    // Obtient le type générique
    Type GenericType = Type.GetType(strGenercType);
     
    // Obtient les types paramètres
    Type[] TypeArgs = new Type[] { Type.GetType(strGenericTypeParam) };
     
    // Construit le type généric avec les bon types paramètres
    Type ConstructedType = GenericType.MakeGenericType(TypeArgs);
     
    // Instancie le type
    Object instance = Activator.CreateInstance(ConstructedType);
     
    // Obtient la méthode
    MethodInfo mi = ConstructedType.GetMethod(strMethodToCall, TypeArgs);
     
    // Obtient la méthode paramétrée
    MethodeInfo miMethod = mi.MakeGenericMethod(TypeArgs);
     
    // Invoque la méthode
    object returned = miMethod.Invoke(instance, Parameters);

    Voila, en gros c'est à peu près ca. Dans ton cas, ta classe statique ne semble pas être une classe template, mais possède des méthodes qui le sont.
    Tu peux donc obtenir directement un Type dessus, et ne pas l'instancier.
    Ensuite obtenir une méthode paramétrée en t'inspirant du code ci-dessus, et l'invoquer en passant null comme référence d'instance (puisque c'est une méthode statique).
    La quasi totalité des méthodes utilisées ont des surcharges qu'il serait intéressant de regarder, ca t'aidera peut-être.

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    201
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 201
    Points : 196
    Points
    196
    Par défaut
    Merci pour cette réponse !

    J'ai donc réussi a faire ce que je voulais !

    Voila un bout de code démonstratif (hors context de mon appli):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    class Program
    {
        static void Main(string[] args)
        {
            Type genericType = Type.GetType("Test.CGeneric");
            Type testType = Type.GetType("Test.CTest");
     
            object oCTest = Activator.CreateInstance(testType);
     
            MethodInfo methodInfo = testType.GetMethod("GenericMethod");
            MethodInfo genericMethodInfo = methodInfo.MakeGenericMethod(new Type[] { genericType });
     
            object oStr = genericMethodInfo.Invoke(oCTest, null);
     
            if (oStr is ICollection)
                foreach (object item in (ICollection)oStr)
                    Console.WriteLine(item);
     
            Console.WriteLine(oStr);
            Console.ReadLine();
        }
    }
     
    class CTest
    {
        public List<T> GenericMethod<T>()
            where T : new()
        {
            return new List<T>() { new T(), new T() };
        }
    }
     
    class CGeneric
    {
        public override string ToString()
        {
            return "Hello World !!!";
        }
    }
    Merci beaucoup ctxnop pour ton aide!

  5. #5
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    Ravis que ca t'ai aidé.
    C'est tout de même super amusant tout ce qu'on peux faire avec la reflection

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 30/08/2004, 14h48
  2. [xsl]simuler le mecanisme OO de "liaison dynamique"
    Par philemon_siclone dans le forum XSL/XSLT/XPATH
    Réponses: 10
    Dernier message: 19/12/2003, 11h34

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