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 :

[C#] Peut-on spécifier un type générique de base pour une liste générique ?


Sujet :

C#

  1. #1
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 824
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 824
    Points : 1 544
    Points
    1 544
    Par défaut [C#] Peut-on spécifier un type générique de base pour une liste générique ?
    Bonjour à tous,

    J'aimerai proposer une liste personnalisée et typée:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    class MaList<T>
    void Add(T objet);
    Le soucis c'est que c'est une liste d'objet commun, mais pas forcément de même type. Donc j'ai pensé à faire un type de base "Entity"

    Mais maintenant, comment imposer au type de ma liste un type qui hérite de Entity?

    C'est pour pouvoir faire des traitements commun sur les Entity de ma liste, sans pour autant mélanger une liste avec plusieurs types différents pour peu qu'ils soient fils de Entity...

    En effet, si je fait un objet qui encapsule une liste et que je propose des méthodes typées genre Add(Entity myEntity), on pourra par la suite ajouter un autre Entity qui est pas forcément du même type que les autres...

    Il existe quelque chose du genre
    ou quelque chose comme ça?

    Merci

    A bientôt
    "Heureusement qu'il y avait mon nez, sinon je l'aurais pris en pleine gueule" Walter Spanghero

  2. #2
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut
    Salut mister3957,

    Donc tu veux creer une liste generique qui stoque des objets dont le type est connu à l'avance.

    C'est un peu contradictoire comme meme et ca n'a aucun interet , tu fais de la genericité pour que les types soient passés en parametres.

    Donc soit tu cree une liste generique et tu specifie lors de sa construction qu'elle est de type Entity, soit tu cree une liste fortement typée qui gere des Entity et des methodes comme tu as fait pour le Add
    Mehdi Feki : Modérateur .Net

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 824
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 824
    Points : 1 544
    Points
    1 544
    Par défaut
    Bah en fait j'ai plusieurs types qui dérivent de Entity, et chacun de ces types à des méthodes communes qui me servent dans ma liste...

    Du coup je voulais typer la classe de base, pour utiliser ces méthodes communes, mais qu'on puisse instancier une liste d'un type bien précis, seulement dérivant de Entity...

    Tu comprends ce que je veux faire?

    Par exemple j'ai plusieurs objet qui on un identifiant, et je voulais m'en servir dans ma liste, pour renvoi un objet à partir de sont identifiant

    Donc par exemple:
    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
     
    class Entity
    {
         int GetId();
    }
    classe Entity1 : Entity
    classe Entity2 : Entity
     
    // Et ma liste:
    Class EntityList<T>
    {
         T Get(int id)
         {
               foreach(T entityIt in m_list)
               {
                     if(entityIt.GetId() == id)
                          return entityIt;
               }
               return null;
         }
    }
    Là ça veut pas parceque le type T n'a pas de méthode GetId(), et quand je fais ((Entity)T).GetId() (en supposant qu'on laisse à l'utilisateur de la classe la précaussion de passer un type issu de Entity, il ne veut pas compiler... et quand bien même ça serait pas terrible.

    Sans ça j'suis obligé de faire une méthode Get(int id) dans chacune de mes classes issues de ma liste... c'est pas top

    Comme ça on peut utiliser les fonction communes dans la liste, et on est sûr que dans la liste on a des objets de même types...

    Tu vois l'truc? On va dire que c'est du semi typage quoi, si ça peut se dire...

    Merci
    "Heureusement qu'il y avait mon nez, sinon je l'aurais pris en pleine gueule" Walter Spanghero

  4. #4
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut
    Oui je comprends tres bien ce que tu veux faire mais je ne comprends pas encore pourquoi tu insiste à utiliser une classe generique alors qu'un truc de ce genre suffira :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Class EntityList
    {
    Entity[] m_list; //ou autre structure
         Entity Get(int id)
         {
               foreach(Entity entityIt in m_list)
               {
                     if(entityIt.GetId() == id)
                          return entityIt;
               }
               return null;
         }
    }
    Tu vois l'truc?
    Mehdi Feki : Modérateur .Net

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2003
    Messages : 835
    Points : 1 046
    Points
    1 046
    Par défaut
    Salut,

    En fait il y a bien un intéret à faire ce que veut mister3957 en .Net, et on peut le faire grace aux contraintes. D'ailleurs sans ça les génériques seraient de bien peu d'utilité : on ne pourrait utiliser que les méthodes du type paramètre appartenant à la classe Object qque soit le type donné en paramètre.

    La syntaxe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    class MaList<T> where T : Entity
    {
     
    }
    Indique au compilateur que T est (ou dérive) de Entity , et donc dans ta classe tu peux utiliser tte les méthodes définies par Entity.

  6. #6
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut
    +1 Sphax

    Le probleme est que j'ai deja lu a propos des contarintes pour les generics mais ca m'ai completement passé à travers .

    Citation Envoyé par Sphax
    D'ailleurs sans ça les génériques seraient de bien peu d'utilité
    Pas tout à fait d'accord sur ce point, les genriques sont tres utils meme sans cette fonctionnalité, d'ailleurs elle est recement introduite dans le framework 2.0
    Mehdi Feki : Modérateur .Net

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Août 2003
    Messages
    835
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2003
    Messages : 835
    Points : 1 046
    Points
    1 046
    Par défaut
    Les génériques sont nouveaux dans .Net2 et les contraintes sont apparues au même moment. Tu ne dois pas bien comprendre que si tu n'indiques aucune contrainte sur tes types paramètres, tu ne peux utiliser dans ta classe générique que les méthodes/propriétés du type Object sur tes arguments de type T (car c'est la seule chose garantie par le framework, tout type dérive de Object) , sinon le compilateur ne compile pas !
    Autrement dit sans contraintes, les génériques ne peuvent servir que de conteneur pur et dur, sans utiliser aucune fonctionalité spécifique au type d'objet passé en argument. Je sais pas si je suis trés clair.

    Exemple :

    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
     
    class MaClasse
    {
       virtual public int GetNumber() { return 10; }
    }
     
    class MaClasseGenerique<T> //sans contrainte
    {
       private T _Membre = default(T);
     
       int GetNumber()
       {
          return T.GetNumber(); //ne compile pas (même si tu n'instancies que des objets de type MaClasseGenerique<MaClasse> !
       }
    }
     
    class MaClasseGeneriqueBis<T> where T : MaClasse
    {
       private T _Membre = default(T);
     
       int GetNumber()
       {
          return T.GetNumber(); //compile , mais n'autorise pas la création de MaClasseGeneriqueBis pour un autre type que MaClass (ou dérivé)
       }
    }
    C'est plus clair ?

  8. #8
    Membre expérimenté
    Avatar de Mehdi Feki
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    1 113
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 113
    Points : 1 566
    Points
    1 566
    Par défaut
    Citation Envoyé par Sphax
    Les génériques sont nouveaux dans .Net2 et les contraintes sont apparues au même moment
    Oui desolé encore une confusion

    Comme je t'ai dit Sphax je connais tres bien les contraintes avec les generics, j'ai deja testé et certes ils ont des avantages, on va dire que les conneries d'hier c'est à cause de la fatigue.

    Ce que je dis, c'est que à la base les generics sont etablis pour permettre de passer des types en paramatere, par exemple au lieu de declarer deux classes :

    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
     
    public class IntList
    {
        private ArrayList _innerList = new ArrayList();
     
        public void Add(int number)
        {
            _innerList.Add(number);
        }
    }
     
    public class FloatList
    {
        private ArrayList _innerList = new ArrayList();
     
        public void Add(float number)
        {
            _innerList.Add(number);
        }
    }
    On utilise les generics :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public class MyList<T>
    {
        private ArrayList _innerList = new ArrayList();
     
        public void Add(T val)
        {
            _innerList.Add(val);
        }
    }
    Sans utiliser les contraintes le gain est immense, autre avantage c'est que ca limite les boxing et unboxing si on utilisait des Object, maintenant revenant à l'histoire des contraintes :
    Je ne vois pas l'interet d'utiliser des generics dans son cas ( à part le fait que c'est une solution à son probleme ) si on connait à l'avance le type qui va être utiliser à moins qu'il existe un avantage que je n'ai pas reussis à trouver. Quelle est la difference dans ce cas entre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
          public class MyList<T> where T : Entity
            {
                private ArrayList _innerList = new ArrayList();
     
                public void Add(T val)
                {
                    _innerList.Add(val);
                }
            }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public class EntityList
            {
                private ArrayList _innerList = new ArrayList();
     
                public void Add(Entity val)
                {
                    _innerList.Add(val);
                }
            }
    Voila j'espere que j'ai été clair
    Mehdi Feki : Modérateur .Net

  9. #9
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 824
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 824
    Points : 1 544
    Points
    1 544
    Par défaut
    Bah c'est excellent c'est tou ce qui me fallait

    Merci beaucoup

    Et sinon est-ce que ce système existe en C++?

    Merci encore
    "Heureusement qu'il y avait mon nez, sinon je l'aurais pris en pleine gueule" Walter Spanghero

  10. #10
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Le plus proche équivalent en C++ des génériques, ce sont les templates. La principale différence est qu'il s'agit d'un mécanisme à la compilation, et que la spécialisation leur offre plus de souplesse (et de complexité). Pour les contraintes, il n'y a pas (encore, c'est bien parti pour les avoir dans la prochaine version de la norme) de vrai équivalent, même si une collection de bidouilles permet dans certains cas d'avoir quelques validations.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  11. #11
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 824
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 824
    Points : 1 544
    Points
    1 544
    Par défaut
    Ha ok d'accord...

    Et la prochaine norme de C++, elle sors bientôt? car j'en entend parler souvent mais on voit rien venir
    "Heureusement qu'il y avait mon nez, sinon je l'aurais pris en pleine gueule" Walter Spanghero

  12. #12
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    C'est prévu pour 2010. Ce qui est plus intéressant, c'est de savoir quand vont sortir des cmpilateurs qui l'implémentent, du moins en partie. Là, ça va AMA varier entre 2008 (la plupart des choses seront fixées à ce moment) et 2015 (après tout, VC++2005 n'implémente pas encore tout ce qu'il y a dans la norme de 1998).
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  13. #13
    Membre expérimenté
    Profil pro
    Inscrit en
    Février 2004
    Messages
    1 824
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2004
    Messages : 1 824
    Points : 1 544
    Points
    1 544
    Par défaut
    Ha ouais ok, on a le temps..

    Bon en tout cas merci beaucoup pour vos réponses

    A bientôt
    "Heureusement qu'il y avait mon nez, sinon je l'aurais pris en pleine gueule" Walter Spanghero

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 23/09/2009, 21h24
  2. Réponses: 2
    Dernier message: 24/06/2009, 12h30
  3. [TableAdapter] Peut-on en faire une liste générique ?
    Par sybaris dans le forum Framework .NET
    Réponses: 4
    Dernier message: 02/10/2008, 15h31
  4. Template pour une saisie générique
    Par strayyy dans le forum Langage
    Réponses: 3
    Dernier message: 05/01/2008, 14h21
  5. Sélection d'un champ d'une liste générique ?
    Par chuiben dans le forum Ada
    Réponses: 2
    Dernier message: 22/03/2007, 14h36

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