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 :

Typed Collection et Heritance


Sujet :

C#

  1. #1
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 177
    Points : 4 489
    Points
    4 489
    Par défaut Typed Collection et Heritance
    Bonjour
    Si il y a des fous , qui se transforme en compilateur, je ne comprend pas pourquoi j'ai un implicite cast

    J'ai les classes suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public class ClientPresenter : MyBasePresenter<ClientModel, IClientView>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public MyBasePresenter<TModel, TView> : Architechture.BasePresenter<TModel, TView>
            where TModel: MyBaseModel, new()
            where TView : Architechture.IBaseView
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public class ClientModel : myBaseModel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public interface IClientView : Architechture.IBaseView
    Quand je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ClientPresenter clientPresenter; 
    myBasePresenter<MyBaseModel, Architechture.IBaseView> basePresenter;
    basePresenter = clientPresenter;
    J'ai un implicite cast et je ne vois pas pourquoi

    Merci
    Je ne suis qu'un pauvre débutant alors ne frappez pas si mes idées ne sont pas bonnes

  2. #2
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 177
    Points : 4 489
    Points
    4 489
    Par défaut
    sinon avec un truc plus simple peut-être

    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
     
        public interface IMyI
        {
        }
     
        class a : IMyI
        {
        }
     
       class myList : List<a>   {  }
     
     
        class Program
        {
            static void Main(string[] args)
            {
                List<IMyI> t;
                myList mylist;
                mylist = new myList();
                t = mylist;
     
            }
        }
    Logiquement t ne devrais pas pouvoir avoir un myList?
    Je ne suis qu'un pauvre débutant alors ne frappez pas si mes idées ne sont pas bonnes

  3. #3
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Points : 8 080
    Points
    8 080
    Par défaut
    Vivivi, c'est ce qu'on appelle la covariance.
    On peut prendre l'exemple avec les List<T>:
    Même si String est un object, List<String> n'est pas une List<object>.
    Depuis .Net 4, c'est un peu plus fin, car la phrase au dessus reste vrai pour List<T> mais pour IEnumerable<T> on a le droit de dire que IEnumerable<String> est un IEnumerable<object>

    http://msdn.microsoft.com/en-us/library/dd233059.aspx

    Pour résumer, ton ClientPresenter qui est un MyBasePresenter<ClientModel, IClientView> n'est pas un MyBasePresenter<MyBaseModel, Architechture.IBaseView>

  4. #4
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 177
    Points : 4 489
    Points
    4 489
    Par défaut
    Donc je dois passer en .Net 4 pour avoir une chance que ca marche?
    Je ne suis qu'un pauvre débutant alors ne frappez pas si mes idées ne sont pas bonnes

  5. #5
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 177
    Points : 4 489
    Points
    4 489
    Par défaut
    Oki et en plus du .Net 4 il faut faire le casting explicitement

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     List<IMyI> t;
                myList mylist;
                mylist = new myList();
                t = mylist.ToList<IMyI>();
    Moins intelligent que je ne le pensais la covariance
    Je ne suis qu'un pauvre débutant alors ne frappez pas si mes idées ne sont pas bonnes

  6. #6
    Membre actif Avatar de brachior
    Homme Profil pro
    Doctorant
    Inscrit en
    Mai 2011
    Messages
    190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Doctorant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2011
    Messages : 190
    Points : 293
    Points
    293
    Par défaut
    C'est malheureusement mon plus gros problème en C# (surement en .NET d'ailleurs Oo)
    J'utilise le Framework 4 et pourtant j'ai du rusé en passant par une interface de marquage Oo
    (merci tomlev ^^)
    Je pense pas que tu doives en arriver jusque là mais je ne sais pas si il y a possibilité de le faire sans le voir comme un object (C# garde en mémoire le type malgré ça ^^)

  7. #7
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 177
    Points : 4 489
    Points
    4 489
    Par défaut
    Tiens je me pose une question quels sont les coûts du casting de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    IMyI myinterface=myA ;
    et 
    List<IMyI> myList= mylist.ToList<IMyI>();
    Je suppose que la covariance est extrèmement coûteuse au niveau ressource
    Vu comme c'est implémenté ca ressemble plus à la création d'un nouvel objet qu'à un casting
    Je ne suis qu'un pauvre débutant alors ne frappez pas si mes idées ne sont pas bonnes

  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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par BenoitM Voir le message
    Je suppose que la covariance est extrèmement coûteuse au niveau ressource
    Non, la covariance c'est gratuit au niveau resources... c'est juste une astuce au niveau du compilateur. Mais ce que tu fais, c'est pas vraiment de la covariance (enfin tu exploites juste le fait qu'un IEnumerable<a> puisse être utilisé là où un IEnumerable<IMyI> est attendu)

    Citation Envoyé par BenoitM Voir le message
    Vu comme c'est implémenté ca ressemble plus à la création d'un nouvel objet qu'à un casting
    Avec le code que tu utilises, effectivement ça crée une nouvelle liste. Ca n'a rien à voir avec la covariance, c'est la méthode ToList qui fait ça.

  9. #9
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 177
    Points : 4 489
    Points
    4 489
    Par défaut
    Sans le toList ca marchait pas.

    Je vais rééssayé un exemple plus propre .

    La c'est parce que List est la "seule" classe typé que j'avais sous la main
    Je ne suis qu'un pauvre débutant alors ne frappez pas si mes idées ne sont pas bonnes

  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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Non mais justement, avec une List<T> la covariance ne marche pas.

    - d'une part parce que ça ne marche que pour les interfaces et delegates, pas les classes concrètes.

    - d'autre part parce que le type T se trouve en entrée ET en sortie de la classe, et que donc la covariance (tout comme la contravariance) ne pourrait pas s'appliquer ici sans casser la sécurité des types. En effet, si tu pouvais appliquer la covariance à List<T>, ça permettrait de faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    List<object> list = new List<string>();
    list.Add(42);
    Ca compilerait sans problème, mais ça pèterait à l'exécution parce que tu essaies d'ajouter un int à une liste de string

    Soit dit en passant, une certaine forme de covariance est possible pour les tableaux, mais c'est considéré aujourd'hui comme un défaut de conception. Ce code compile, mais lève une exception :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    object[] array = new string[2];
    array[0] = 42; // ArrayTypeMismatchException

  11. #11
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 177
    Points : 4 489
    Points
    4 489
    Par défaut
    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
     
     public class VehiculeAMoteur<Mot>
        where Mot:Moteur {  }
     
        public class Moteur
        {
        }
     
        public class Train<MoteurElectrique> : VehiculeAMoteur<Moteur>
        {
        }
     
        public class MoteurElectrique : Moteur { }
     
        class Program
        {
            static void Main(string[] args)
            {
                VehiculeAMoteur<Moteur> vehiculeAMot;
                Train<MoteurElectrique> Train=new Train<MoteurElectrique>();
                vehiculeAMot = Train;            
            }
        }
    Ici il me semble que je fais la même chose que ce que je voulais faire au début
    Et ca marche même en .Net 3.5

    Je vais réssayer mes classes d'origines pour voir si j'ai pas loupé un truc
    Je ne suis qu'un pauvre débutant alors ne frappez pas si mes idées ne sont pas bonnes

  12. #12
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 177
    Points : 4 489
    Points
    4 489
    Par défaut
    Autre question quelle est la différence entre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    public class VehiculeAMoteur<Mot>
    where Mot:Moteur {  }
    et
    public class VehiculeAMoteur<Moteur>
    Je ne suis qu'un pauvre débutant alors ne frappez pas si mes idées ne sont pas bonnes

  13. #13
    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 : 42
    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
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par BenoitM Voir le message
    Ici il me semble que je fais la même chose que ce que je voulais faire au début
    Bah oui mais dans ton exemple Train<MoteurElectrique> hérite de VehiculeAMoteur<Moteur>, donc c'est normal que ça marche... Dans ce que tu as écrit, il n'y a aucun lien entre MoteurElectrique (le paramètre de type, pas la classe) et Moteur
    (soit dit en passant, le fait d'utiliser le même nom pour une classe et pour un paramètre de type générique ne facilite pas la compréhension...)

    Tu ne pourrais pas affecter, par exemple, un VehiculeAMoteur<MoteurAExplosion> à un VehiculeAMoteur<Moteur>, même si MoteurAExplosion hérite de Moteur


    Citation Envoyé par BenoitM Voir le message
    Autre question quelle est la différence entre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    public class VehiculeAMoteur<Mot>
    where Mot:Moteur {  }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public class VehiculeAMoteur<Moteur>
    Dans la 2eme déclaration, Moteur est un paramètre de type, ce n'est pas la classe Moteur. D'où ma remarque précédente... normalement pour les paramètres de type on préfixe le nom par T pour éviter ce genre de confusion :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public class VehiculeAMoteur<TMoteur>
        where TMoteur : Moteur
    {
    }

  14. #14
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Points : 8 080
    Points
    8 080
    Par défaut
    De l'exterieur: aucune!
    De l'interieur: plein de chose!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public class Moteur
    {
        public void Avancer()
        {
            //Vroum
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    public class VehiculeAMoteur<TMoteur>
    {
        public TMoteur MonMoteur {get;set;}
        public void Avancer()
        {
            // MonMoteur est ici un object, on ne peut pas acceder à MonMoteur.Avancer()
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public class VehiculeAMoteur<TMoteur>
        where TMoteur : Moteur
    {
        public TMoteur MonMoteur {get;set;}
        public void Avancer()
        {
            MonMoteur.Avancer(); //Avec la contrainte on sait que MonMoteur est un Moteur
        }
    }

  15. #15
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 177
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 177
    Points : 4 489
    Points
    4 489
    Par défaut
    Merci

    Avec un petit test c'est plus facile pour comprendre
    Je ne suis qu'un pauvre débutant alors ne frappez pas si mes idées ne sont pas bonnes

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

Discussions similaires

  1. Convertir un type collection au type set
    Par sonia5 dans le forum Collection et Stream
    Réponses: 1
    Dernier message: 24/06/2009, 13h18
  2. Les generics, hors les types collection ?
    Par jeanfr dans le forum Langage
    Réponses: 10
    Dernier message: 24/11/2008, 13h02
  3. [nested] récupérer une propriété de type collection
    Par kokumbo dans le forum Struts 1
    Réponses: 2
    Dernier message: 25/10/2007, 16h16
  4. Requete sur un champ de type collection
    Par Dev_info dans le forum Hibernate
    Réponses: 4
    Dernier message: 19/10/2007, 13h03
  5. Controle ActiveX : propriété de type Collection
    Par irreantum dans le forum VB 6 et antérieur
    Réponses: 12
    Dernier message: 26/03/2007, 12h54

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