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 :

Type Génériques Erreur


Sujet :

C#

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Août 2014
    Messages : 11
    Points : 7
    Points
    7
    Par défaut Type Génériques Erreur
    Bonjour,

    Il y a un truc que je ne comprend pas sur les génériques... Si quelqu'un voulait bien m'expliquer ce serait gentil...

    J'ai un "Catalogue<T>" où "T" est une classe dérivant obligatoirement de "ElementCatalogue".

    "ElementCatalogue" a par exemple deux classe filles "ElementCatalogueMeubles" et "ElementCataloguePieces".

    Si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Catalogue<ElementCatalogue> catalogue = new Catalogue<ElementCataloguePieces>();
    Pourquoi ai-je une erreur ?

    Quel serait alors la bonne pratique a mettre en place ?

  2. #2
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 153
    Points : 25 071
    Points
    25 071
    Par défaut
    question qui passe de temps en temps, certains parlent de covariance ou autre ...

    enfin ce qu'il y a à retenir c'est que même si B hérite de A et que B peut etre rangé dans une variable de type A
    une collection B n'a rien à voir avec une collection de A, les élements d'une collection de B pourrait rentrer dans un collection de A certes mais ca s'arrête là

    soit tu types sur <A> soit sur <B> mais l'instance doit correspondre au type
    le type n'est pas catalogue mais bien catalogue<T>



    après rien n'empeche de filtrer avec .OfType par exemple pour n'avoir que ceux d'un type
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Personnellement je ne comprends pas pourquoi catalogue est générique en premier lieu.
    Elle semble devoir contenir un ensemble de ElementCatalogue, ceux-ci pouvant aussi bien être des ElementCataloguePieces que des ElementCatalogueMeubles. Ça reste à une simple composition pour moi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Catalogue
    {
        private List<ElementCatalogue> elements;
     
        //...
        public void Add (ElementCatalogue element)
        {
            elements.Add (element);
        }
    }
    Du point de vue de la méthode Add, qu'on lui donne ElementCatalogue, ElementCataloguePieces ou ElementCatalogueMeubles ça ne fait aucune différence
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  4. #4
    Expert confirmé
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 4 062
    Points
    4 062
    Par défaut
    Par défaut la généricité n'est en effet pas covariante.

    Pour ce faire il faut passer par des interfaces et spécifier la nature covariante via out :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    interface ICatalogue<out T>
    {
        ...
    }
     
    class Catalogue<T> : ICatalogue<T>        
    {
        ...
    }
     
    ....
     
    ICatalogue<ElementCatalogue> catalogue = new Catalogue<ElementCataloguePieces>();
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

  5. #5
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Citation Envoyé par Seb02859 Voir le message
    Pourquoi ai-je une erreur ?
    Parce que si cela ait été autorisé il deviendrait licite d'assigner un ElementCataloguePieces à une collection d'ElementCatalogueMeubles castée en collection d'ElementCatalogue !

    De deux choses l'une :
    * Soit tu n'as besoin de ce cast que pour un accès en lecture et alors une interface covariante est la bonne réponse. C'est par exemple le cas d'IEnumerable (il est licite de caster un IEnumerable<ElementCatalogueMeubles> en IEnumerable<ElementCatalogue>), IReadOnlyCollection<T> et IReadOnlyList<T>.

    * Ou alors tu as bel et bien besoin d'un accès en écriture et dans ce cas soit tu as une erreur de conception, soit tu es obligé de recourir à une sale ficelle pour te sortir d'une ornière, auquel cas une interface non-générique commune IElementCatalogue { void Add(ElementCatalogue) } est la meilleure chose à faire. Mais je t'invite à d'abord à vérifier ta conception.

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2014
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Août 2014
    Messages : 11
    Points : 7
    Points
    7
    Par défaut
    Merci des réponses, je me penche de nouveau sur le problème.


    Citation Envoyé par Sehnsucht Voir le message
    Personnellement je ne comprends pas pourquoi catalogue est générique en premier lieu.
    Elle semble devoir contenir un ensemble de ElementCatalogue, ceux-ci pouvant aussi bien être des ElementCataloguePieces que des ElementCatalogueMeubles. Ça reste à une simple composition pour moi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Catalogue
    {
        private List<ElementCatalogue> elements;
     
        //...
        public void Add (ElementCatalogue element)
        {
            elements.Add (element);
        }
    }
    Du point de vue de la méthode Add, qu'on lui donne ElementCatalogue, ElementCataloguePieces ou ElementCatalogueMeubles ça ne fait aucune différence
    En fait à la base la classe catalogue n'est censé n'avoir qu'un type d'élément catalogue "ElementCataloguePieces" ou "ElementCatalogueMeubles" mais pas les deux !



    Je n'ai pas totalement compris la notion de la covariance, je vais de ce pas faire quelques recherches.


    Je pense qu'il s'agit d'une erreur de conception, je n'ai pas eu l'occasion de faire beaucoup de conception et il est fort probable que l'erreur vienne de la...



    Il me faudrait alors peut être faire un tableau contenant tous les Catalogue<ElementCataloguePieces> et Catalogue<ElementCatalogueMeubles>.
    Une classe ICatalogue permettant de faire un tableau serait-elle une bonne solution ?

  7. #7
    Expert confirmé
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Points : 4 062
    Points
    4 062
    Par défaut
    Non tu n'as pas nécessairement d'erreur de conception.

    Sinon on peut considérer que la plupart des langages en ont fait une énorme en permettant d'avoir string[], int[], double[]... alors qu'on peut se contenter d'object[] !
    Il ne faut pas confondre généricité et polymorphisme.

    Et si Microsoft a dépensé des sous pour implémenter la covariance c'est que c'était vraiment un besoin très important de la communauté des développeurs.
    (Sache que développer la moindre feature coûte une blinde c'est pour ça que de nombreuses features n'ont jamais été implémentées même si le besoin est bien là : un sou est un sou.)
    Et en effet j'ai eu plusieurs fois besoin de me servir de cette covariance.

    Après tu peux parfois t'en passer et "feinter" : e.g. si ton catalogue implémente IEnumerable<T> alors tu bénéficies de la covariance de l'interface IEnumerable<T> sans avoir à implémenter toi même une interface dédiée comme je l'ai fait.
    Mais dans ce cas tu es limité au contrat d'IEnumerable<T> donc à voir si les traitements qui utilisent les Catalogues peuvent s'en contenter.
    Formateur expert .Net/C#/WPF/EF Certifié MCP disponible sur Paris, province et pays limitrophes (enseignement en français uniquement).
    Mon blog : pragmateek.com

Discussions similaires

  1. Réponses: 4
    Dernier message: 15/07/2011, 13h04
  2. [Framework] IOC - Type générique
    Par seawolfm dans le forum Spring
    Réponses: 1
    Dernier message: 06/02/2007, 18h17
  3. Réponses: 12
    Dernier message: 23/09/2006, 12h12
  4. try et type d'erreur à catcher.
    Par tomy29 dans le forum Delphi
    Réponses: 20
    Dernier message: 03/08/2006, 12h19
  5. y a-t-il un support de types génériques pour python ?
    Par silverhawk.os dans le forum Général Python
    Réponses: 15
    Dernier message: 24/03/2006, 18h23

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