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 :

IList, ObservableCollection, polymorphisme et cast


Sujet :

C#

  1. #1
    Modérateur
    Avatar de Flaburgan
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2010
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 229
    Par défaut IList, ObservableCollection, polymorphisme et cast
    Bonjour,

    J'ai un petit souci et je ne comprends pas pourquoi.
    Soient A et B deux classes avec B qui héritent de A

    J'ai une liste déclarée comme suis :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    IList<B>listeDeB = new ObservableCollection<B>();

    J'ai une méthode avec le prototype suivant :

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    void MaMethode(IList<A> uneListe);

    Je n'arrive pas à faire
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    MaMethode(listeDeB);
    (methode has some invalide argument).

    Déjà là je ne comprends pas bien, puisque B hérite de A, je devrais pouvoir l'appeler, mais admettons. Je caste donc ma liste ainsi :
    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    MaMethode((IList<A>)listeDeB)
    et là j'obtiens :
    Unable to cast object of type 'System.Collections.ObjectModel.ObservableCollection to type 'System.Collections.Generic.IList

    Hum... Quelqu'un peut m'expliquer ?

  2. #2
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Bonjour

    Si tu es en framework 3.5, il n'y a pas de solution directe à ton problème.

    Si tu es en 4.0 ou + , je te suggère d'aller voir les notions de covariance et contravariance de généricité.

    Ici :

    http://msdn.microsoft.com/fr-fr/library/dd799517.aspx

  3. #3
    Membre Expert
    Avatar de GuruuMeditation
    Homme Profil pro
    .Net Architect
    Inscrit en
    Octobre 2010
    Messages
    1 705
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : Belgique

    Informations professionnelles :
    Activité : .Net Architect
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2010
    Messages : 1 705

  4. #4
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par GuruuMeditation Voir le message
    Désolé , je ne connaissais pas ton article sur le sujet, sinon c'est celui que j'aurais mis en lien

  5. #5
    Modérateur
    Avatar de Flaburgan
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2010
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 229
    Par défaut
    Je suis en 3.5 et je ne peux pas passer en 4.

    Alors je fais quoi moi

    Au passage, je tiens pas particulièrement à IList, je peux mettre ce que vous voulez à la place, par contre j'ai besoin de mon ObservableCollection.

    Si je mets ICollection partout à la place de IList, ça va marcher ?

  6. #6
    Modérateur
    Avatar de Flaburgan
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2010
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 229
    Par défaut
    En fait là j'ai un héritage à la fois au niveau de l'objet et de la collection, si je mets partout la collection et que j'ai plus qu'un héritage sur l'objet, ça marcherait ?

    Edit : Visiblement non, j'ai mis ObservableCollection<> partout et il me dit que l'argument est invalide si je cast pas, et qu'il peut pas caster si je mets (ObservableCollection<A>) devant la listObservableCollection<B>

  7. #7
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par Flaburgan Voir le message
    En fait là j'ai un héritage à la fois au niveau de l'objet et de la collection, si je mets partout la collection et que j'ai plus qu'un héritage sur l'objet, ça marcherait ?
    Tu n'as pas d'héritage au niveau de la collection, c'est justement le problème.
    Ton problème vient d'une relative mécompréhension (fréquente, je te rassure) de la généricité.

    Considèrons une classe générique A :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class A<T> where T : class
    {
    T aMember;
    }
    Il faut comprendre que les classes A<int> et A<string> n'ont aucun antécesseur commun, contrairement à ce qu'on pourrait instinctivement supposer.
    En effet, la classe générique A<T> n'est pas une classe au sens habituel, c'est à dire une entité instanciable ou adressable comme référence (cas d'une class abstraite).

    Elle n'a d'existence en temps que classe que au moment où tu donne une signification à son paramètre de généricité. Il faut (avec beaucoup de nuances !) considérer A<T> comme une sorte de "macro" qui ne devient une classe que dès l'instant où T prend une signification.

  8. #8
    Modérateur
    Avatar de Flaburgan
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2010
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 229
    Par défaut
    J'ai vu en effet que ça ne marchait pas (j'ai édité mon message ci-dessus), mais alors, quelle solution... ?

  9. #9
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Par défaut
    Citation Envoyé par Flaburgan Voir le message
    J'ai vu en effet que ça ne marchait pas (j'ai édité mon message ci-dessus), mais alors, quelle solution... ?
    Une, simple, consiste à stocker ta liste d'instance de B dans une liste de A (comme B hérite de A).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    B instanceDeB = new B();
    List<A> maListeDeB = new List<A>();
    maListeDeB.Add(instanceDeB);
    est parfaitement valide.

  10. #10
    Modérateur
    Avatar de Flaburgan
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2010
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2010
    Messages : 1 229
    Par défaut
    Oui oui, c'est ce que j'ai fait depuis le début, c'est au moment de passer les paramètres...

    ça voudrait dire que ma première méthode doit rester plus générique, mais ça me plaisait pas trop.

    Je vais voir ce que je fais, en tout cas, ça a répondu à ma question initiale, merci

  11. #11
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Une autre solution, si tu as la main sur la méthode à appeler, est de relâcher sa définition, de cette façon:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void MaMethode<T>(IList<T> uneListe) where T : A
    Selon le contenu de la méthode en question, ce sera possible ou pas.

    Sinon, pour reprendre ce que disais BlueDeep, essaie de voir si en fait ta méthode ne se contenterait pas d'un IEnumerable. A cemoment là, tu pourrais bénéficier gratos de la covariance de IEnumerable<T>.

    Pour compléter encore ce que dit BlueDeep, un exemple parlant: même si A hérite de object, List<A> n'hérite pas de List<object>, parce que tu peux appeler Add(new B()) sur une liste d'objets, mais pas sur une liste de A.

  12. #12
    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 : 39
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Citation Envoyé par Guulh Voir le message
    Sinon, pour reprendre ce que disais BlueDeep, essaie de voir si en fait ta méthode ne se contenterait pas d'un IEnumerable. A cemoment là, tu pourrais bénéficier gratos de la covariance de IEnumerable<T>.
    Oui mais qu'avec .Net >= 4

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

Discussions similaires

  1. Polymorphisme en évitant les casts
    Par dagera dans le forum Langage
    Réponses: 14
    Dernier message: 14/10/2011, 18h36
  2. Réponses: 2
    Dernier message: 05/01/2010, 11h21
  3. Réponses: 10
    Dernier message: 17/07/2008, 20h01
  4. Polymorphisme et cast dynamique
    Par vcoulon dans le forum C++
    Réponses: 16
    Dernier message: 21/03/2007, 14h03
  5. traduction en delphi "reinterpreted cast"
    Par Chupakabra dans le forum Langage
    Réponses: 3
    Dernier message: 13/02/2003, 15h49

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