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

Windows Forms Discussion :

[C#] Reflection et Construction générique


Sujet :

Windows Forms

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Par défaut [C#] Reflection et Construction générique
    Edit:

    Re bonsoir,

    Je voudrais créer un objet a partir d'une classe perso mais je me retrouve avec l'exception ArgumentNullException typeName is nullNothingnullptra null reference (Nothing in Visual Basic). sur mon GetType()

    Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Object oObject = Activator.CreateInstance(Type.GetType(s));
    Où 's' est une String. Je lui ai donnée 2 valeurs mais aucune n'a fonctionnée ("DummyClass" et "TestApplication.DummyClass")

    DummyClass est ma classe et TestApplication le namespace ou se trouve la classe.

    Je ne comprends pas ce qui ne va pas.. :s

    Precision : Je ne veut pas lui passer le Type directement, c'est à dire Activator.CreateInstance(typeof(DummyClass)) car j'aimerai que ce soit generic.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Tu sais qu'il y a déjà des classes qui gèrent la sérialisation XML ? pas la peine de gérer ça à la main, heureusement !
    Jette un oeil à la classe System.Xml.Serialization.XmlSerializer

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Par défaut
    Oui je sais mais je souhaite faire un Serializer custom, dans lequel je pourrais gérer n'importes quels type (classe perso, List, Hashtables, etc..)

  4. #4
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Par défaut
    Citation Envoyé par LoST_MiNd Voir le message
    Oui je sais mais je souhaite faire un Serializer custom, dans lequel je pourrais gérer n'importes quels type (classe perso, List, Hashtables, etc..)
    Ben pour les classes perso il suffit qu'elles aient l'attribut [Serializable]
    Pour les collections il suffit de faire une petite méthode qui prend en parametre un IEnumerable<T> et pour les dictionnaires (Hastable ou Dictionnary ) même principe.

    Pas la peine de réinventer la roue à chaque developpement

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Par défaut
    Hm oki, c'est vrai que ca serait plus simple , mais je dois le faire comme ça...

    Donc en mettant le probleme dans un contexte plus restreint :

    Comment je peux créer un Object de type String[] et lui donner comme valeur un tableau d'objet contenant des String

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Type tabobject = Type.GetType(xmlNodePropertyList[i].Attributes["type"].Value);
    Ceci fonctionne, j'ai bien là un Type de type String[] mais de réference nulle.

    Comment je peux l'instancier et lui affecter une valeur ?

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par dev01 Voir le message
    Ben pour les classes perso il suffit qu'elles aient l'attribut [Serializable]
    Pour la sérialisation XML ce n'est pas nécessaire...

    Sinon c'est vrai que la sérialisation XML a quelques limitations, notamment ça ne marche pas pour les Hashtable ou Dictionary... je ne vois pas très bien pourquoi d'ailleurs, il suffirait de faire une structure comme ça:
    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <Dictionary>
        <KeyValuePair>
            <Key>titi</Key>
            <Value>toto</Value>
        </KeyValuePair>
    </Dictionary>
    ou quelque chose d'approchant...

    De toutes façons, il est toujours possible de customiser plus finement la sérialisation avec les attributs de System.Xml.Serialization ou en implémentant l'interface IXmlSerializable

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Par défaut
    Car les dictionnary peuvent avoir n'importe quel type je crois.

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par LoST_MiNd Voir le message
    Car les dictionnary peuvent avoir n'importe quel type je crois.
    oui, mais du moment que de sont des types sérialisables en XML, je ne vois pas où est le problème...

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Par défaut
    Citation Envoyé par LoST_MiNd Voir le message
    Hm oki, c'est vrai que ca serait plus simple , mais je dois le faire comme ça...

    Donc en mettant le probleme dans un contexte plus restreint :

    Comment je peux créer un Object de type String[] et lui donner comme valeur un tableau d'objet contenant des String

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Type tabobject = Type.GetType(xmlNodePropertyList[i].Attributes["type"].Value);
    Ceci fonctionne, j'ai bien là un Type de type String[] mais de réference nulle.

    Comment je peux l'instancier et lui affecter une valeur ?
    Une petite idée juste pour ça svp ?

  10. #10
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Je suis pas sûr que ce soit ça ta question, mais pour créer un tableau d'un type que tu ne connais pas à l'avance, tu peux utiliser Array.CreateInstance(Type elementType, Int32 length)

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Par défaut
    Re bonsoir,

    Je voudrais créer un objet a partir d'une classe perso mais je me retrouve avec l'exception ArgumentNullException typeName is nullNothingnullptra null reference (Nothing in Visual Basic). sur mon GetType()

    Voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Object oObject = Activator.CreateInstance(Type.GetType(s));
    Où 's' est une String. Je lui ai donnée 2 valeurs mais aucune n'a fonctionnée ("DummyClass" et "TestApplication.DummyClass")

    DummyClass est ma classe et TestApplication le namespace ou se trouve la classe.

    Je ne comprends pas ce qui ne va pas.. :s

    Precision : Je ne veut pas lui passer le Type directement, c'est à dire Activator.CreateInstance(typeof(DummyClass)) car j'aimerai que ce soit generic.

  12. #12
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Il faut passer en paramètre de GetType le nom complet du type, y compris l'assembly (sauf si le type est dans l'assembly courant).
    Sinon il faut que tu cherches le type dans chaque assembly chargé dans l'AppDomain :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public Type FindType(string typeName)
    {
        foreach(Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
        {
            Type t = asm.GetType(typeName);
            if (t != null)
                return t;
        }
        return null;
    }
    Ou si tu es en 3.5 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public Type FindType(string typeName)
    {
        return (from t in AppDomain.CurrentDomain.GetAssemblies().SelectMany(asm => asm.GetTypes())
            where t.FullName == typeName
            select t).FirstOrDefault();
    }

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Par défaut
    Super la version 3.5, j'avais trouvé en passant la QualifiedAssemblyName direct.

    Mais là je retombe sur un nouveau probleme... Les tableaux de classe perso..

    J'ai beau utiliser ta fonction ou passer le nom de l'assembly complet, j'ai soit un argumentNullException avec ta fonction ou bien MissingMethodConstruction pour l'assembly complet.. Dois-je ajouter un constructeur particulier dans ma classe ? (j'ai mis un constructeur vide au cas ou mais rien...)

    Je ne pense pas que la méthode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public static Object CreateInstance(
        Type type,
        params Object[] args
    )

    Fonctionne étant donné que ce sont des args par rapport au constructeur, sans rapport avec une instance d'un tableau de classe ? (ex: MaClass[])

  14. #14
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    A priori ceci devrait marcher...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Type.GetType("MaClass[]")
    Regarde la doc de Type.GetType, il y a pas mal de détails sur les noms de types à passer en paramètre
    http://msdn.microsoft.com/fr-fr/library/w3f99sx1.aspx

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Par défaut
    Oui j'ai regardé ça, en fait je peux pas passer MaClass[] tout seul car ma fonction est dans une assembly séparé de mon Main. Donc je passe en paramétre le AssemblyQualifiedName et ça marche à peut prêt, car il me donne un nouvelle erreur qui est : Aucun constructeur sans paramètre défini pour cet objet.

    Or ma DummyClass ressemble à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public class DummyClass
        {
            public int a = 42;
            public float b = 42.42F;
     
            public DummyClass() { }
        }
    Je peux pas faire plus vide que ça comme constructeur :s

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    29
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 29
    Par défaut
    Bon ben je bloque...

    Meme un simple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Object myObject = Activator.CreateInstance(Type.GetType("System.String[]"));
    Me retourne une erreur comme quoi il ne trouve pas de constructeur pour ce type..
    Ya t-il une astuce que je vois pas ? Contruire un String simple puis le "transformer" en tableau ? ... Je suis un peu pommé ^^

  17. #17
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    String ou DummyClass ont un constructeur par défaut, mais pas String[] et DummyClasse[]... je ne sais pas trop à quoi ressemble le constructeur d'un tableau, vu que normalement on en n'a jamais besoin.
    Le plus simple à mon avis est d'obtenir le type des éléments du tableau (donc String ou DummyClass en l'occurence) et créer le tableau avec Array.CreateInstance

Discussions similaires

  1. Réponses: 5
    Dernier message: 01/02/2011, 15h34
  2. Utilisation de la reflection avec des génériques
    Par Tekarihoken dans le forum Framework .NET
    Réponses: 2
    Dernier message: 25/01/2011, 18h06
  3. Réponses: 1
    Dernier message: 17/12/2008, 20h24
  4. [JBuilder 7] Construction d'executable natif
    Par renaudfaucon dans le forum JBuilder
    Réponses: 3
    Dernier message: 24/11/2006, 22h28
  5. Reflections
    Par Laurent Gomila dans le forum DirectX
    Réponses: 4
    Dernier message: 25/07/2003, 14h42

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