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 :

list générique et type


Sujet :

C#

  1. #1
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 30
    Points : 20
    Points
    20
    Par défaut list générique et type
    Bonjour,

    J'utilise une list générique d'un objet défini : par exemple client qui dérive d'un objet tt.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public class tt {}
    public class client : tt {}
    list<client> lstclient = new list<client>();
    Pour remplir une datagridview, je passe ma liste comme datasource :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     datagridview1.DataSource = lstclient;
    Dans une autre classe, j'aimerai vérifier que mon datasource de mon datagridview est une list<tt>, est-ce possible ?

    le but est d'avoir une fonction générique si je crée une classe commande qui hérite aussi de tt.

    Si je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     if (datagridview1.DataSource is list<client>)
    , celà fonctionne, il me renvoie bien true, alors que si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     if (datagridview1.DataSource is list<tt>)
    , celà retourne false.

    Si vous avez des idées, je vous remercie d'avance.

  2. #2
    Membre averti Avatar de Seth77
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2005
    Messages
    1 448
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 448
    Points : 410
    Points
    410
    Par défaut
    Salut

    C normal tu utilises une liste de Client et non de tt, meme si Client derige de tt ; ce que tu peux faire c verifier que le type Client derive de tt.


  3. #3
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 30
    Points : 20
    Points
    20
    Par défaut
    Merci de ta réponse Seth77

    Et je fais celà comment ???

    Merci de ta réponse.

  4. #4
    Membre éprouvé Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Points : 1 188
    Points
    1 188
    Par défaut
    c'est bien normal, client dérive de tt, donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    classpersonne
    {
    }
    classhomme : personne
    {
    }
    et ensuite

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    personne p = newpersonne();
    homme h = newhomme();
    if (p ishomme) //revoie false
    MessageBox.Show("personne est un homme");
    if (h ispersonne)//revoie true
    MessageBox.Show("homme is personne");
    alors que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    List<personne> p = newList<personne>();
    List<homme> h = newList<homme>();
    if (p isList<homme>)//renvoie faux
    MessageBox.Show("liste personne est une liste homme");
    if (h isList<personne>)//renvoie faux
    MessageBox.Show("liste homme est une liste  personne");

    tu compares des list<T> mais pas les objets contenus dans la collection.
    Par contre si tu faisait ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    classpersonnes:List<personne>
    {
    }
    classhommes : personnes
    {
    }
    en faisant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    personnes p = newpersonnes();
    hommes h = newhommes();
    if (p is hommes) //revoie false
    MessageBox.Show("personnes est un hommes");
    if (h is personnes)//revoie true
    MessageBox.Show("hommes is personnes");
    ça changerai tout, ça fonctionnerai comme tu veux...
    Essayes et tu verra

  5. #5
    Membre éprouvé Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Points : 1 188
    Points
    1 188
    Par défaut
    Si c'est résolu, n'oublie pas le :

  6. #6
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 30
    Points : 20
    Points
    20
    Par défaut
    Merci de ton explication sisqo60.

    Ce que je suis en train de faire est un niveau plus compliqué :

    j'ai ma classe personne, mes classes homme,femme,enfant et une liste générique personnalisé.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public class personne{}
    public class homme : personne{}
    public class femme : personne{}
    public class enfant : personne{}
    public class persolist<T> : List<T> where T : personne
    J'ai fait cette list perso pour pouvoir implementer une sauvegarde de la list après chargement et pouvoir restaurer à la situation initiale si je veux annuler mes changements que l'utilisateur a fait dans sa grille.

    Je crée ensuite des classes listhomme, listfemme et des objets correspondants que je mets en datasource d'une datagridview :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     public class listhomme : persolist<homme>
    private listhomme listho = new listhomme;
    listo.Add(new homme("HOMME 1");
    listo.Add(new homme("HOMME 2");
    datagridview1.DataSource = listho;
    Maintenant je veux faire un traitement spécifique dans une méthode au cas où ma datasource est bien un objet persolist. Et c'est là que je coince même avec tes explications.

    Encore merci de votre aide.

  7. #7
    Membre éprouvé Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Points : 1 188
    Points
    1 188
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    public class persolist : List<T> where T : personne
    plutot comme ça...

  8. #8
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 30
    Points : 20
    Points
    20
    Par défaut
    Citation Envoyé par sisqo60 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    public class persolist : List<T> where T : personne
    plutot comme ça...
    Si je l'enlève le T dans la première partie, celà ne compile plus et j'ai le message les contraintes ne sont pas autorisées sur des déclarations non générique.

    Et si je l'enlève le <T> dans ma déclaration de persolist , je ne pourra plus écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public class listhomme : persolist<homme>
    .

    J'aimerai tester un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (DatagridView1.DataSource is persolist)
    (persolist)DatagridView1.DataSource.Restore();
    sauf que je ne peux le faire du fait du générique.

    C'est stressant d'imaginer des traitements que l'on arrive pas à coder .....

  9. #9
    Membre éprouvé Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Points : 1 188
    Points
    1 188
    Par défaut
    ça commençe à être longuet mais c'est mieux et tu pourrais y arriver :

    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
    classpersonne
    {
    }
    classhomme : personne
    {
    }
    classfemme : personne
    {
    }
    classlistePersonnes<T> : List<T> where T : personne
    {
    }
    classpersonnes : listePersonnes<personne>
    {
    }
    classhommes : listePersonnes<homme>
    {
    }
    classfemmes : listePersonnes<femme>
    {
    }
    

  10. #10
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 30
    Points : 20
    Points
    20
    Par défaut
    Merci de ton aide sisqo60. Je sais que c'est longuet mais celà fait plus d'une journée que je bloque là dessus.

    Si je fais une classe par objet fils, je perds tout l'intérêt du générique et là j'ai pris un exemple qui avait 3 classes dérivées, mais moi je risque d'arriver à plus de 100 classes dérivées (une classe par table de ma base en fait).

    Le but étant de dupliquer le moins possible de code dans les fils et donc dans faire un max dans les parents.

    Si je prends ta solution, je suis obliger de créer une classe list par table.
    Ensuite il faut que je fasse un enum de mes classes list et tester ensuite que le type de mon Datasource est bien dans l'enumération.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     if (DatagridView1.DataSource in LstEnum)
    Celà me semble bien compliqué quand même ....

  11. #11
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 30
    Points : 20
    Points
    20
    Par défaut
    Pour m'aider,

    As-t-on un moyen de retrouver le type passé à un générique ?

    Avec la ligne de Code Suivante, je trouve que mon type est bien un générique.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     DatagridView1.DataSource.GetType().IsGenericType
    Si je fais un messagebox de mon GetType, je vois bien
    persolist`1 [homme]

    Mais je ne trouve rien me permettant d'obtenir mon type homme

  12. #12
    Membre éprouvé Avatar de sisqo60
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2006
    Messages
    754
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 754
    Points : 1 188
    Points
    1 188
    Par défaut
    si ton datasource n'est pas vide, tu peux faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    IList liste = datagridview.datasource;
    if (liste != null && liste.count>0)
    {
       liste[0].getType().name;//ou autrement...
    }
    Mais je ne suis pas très convaincu de son optimisation...

  13. #13
    Membre confirmé Avatar de MetalGeek
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    412
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 412
    Points : 513
    Points
    513
    Par défaut
    Salut,
    tu peux sinon dériver la classe List<t>, créer une interface et créer des classes du style ttList : List<tt>, IGetItemType en en y ajoutant une méthode GetItemType() tirée de l'interface qui te renverrait le type des objets. Après tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    var listeDeTT = machintruc.DataSource as IGetItemType;
    if(lisetDeTT != null)
    {
        var type = listeDeTT.GetItemType();
        //if (type == typeof(tt)...)
    }
    Mais ceci dit, en général quand tu travailles avec des types génériques et que tu te retrouves plus tard à tester les types, c'est qu'il y a un problème de conception quelque part, sinon les types génériques ne serviraient à rien.

  14. #14
    Membre à l'essai
    Inscrit en
    Décembre 2008
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Décembre 2008
    Messages : 30
    Points : 20
    Points
    20
    Par défaut
    Je crois que j'ai trouvé une solution à mon problème en utilisant une interface.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Public interface I_MonInterface
    {
         Void Restore() ;
    }
    Je déclare ensuite ma list générique héritant de cette interface

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public class persolist<T> : List<T>,I_MonInterface where T : personne
    {
         public void Restore();
    }
    Je peux ensuite faire le test suivant dans les autres classes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    I_MonInterface imi = DataGridView.DataSource as I_MonInterface;
    if (imi != null)
        imi.Restore
    Et là le code qui est contenu dans la méthode Restore de la liste générique est bien lancé.

    Merci à tout ceux qui sont intervenus sur ce post. Si quelqu'un a une autre solution, je suis toujours preneur.

Discussions similaires

  1. Réponses: 4
    Dernier message: 01/04/2019, 18h52
  2. Liste générique de types génériques
    Par le2tbomi dans le forum VB.NET
    Réponses: 7
    Dernier message: 17/07/2008, 23h16
  3. Réponses: 12
    Dernier message: 23/09/2006, 12h12
  4. Liste exhaustive des types de jeux-vidéo
    Par alex6891 dans le forum Développement 2D, 3D et Jeux
    Réponses: 2
    Dernier message: 03/05/2006, 10h34
  5. Affichage de listes de différents types
    Par thibouille dans le forum C++
    Réponses: 9
    Dernier message: 27/11/2005, 19h34

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