Bonjour,
J'ai eu un soucis récemment avec le polymorphisme dans une liste.
Je vais poser le problème avant, ça sera peut être plus clair :
J'ai une classe abstraite A, et deux classes (B et C) qui en héritent :
Je veux faire un traitement quelconque sur une liste de ces objets (B et C).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 public abstract class A { public string Value { get; set; } } public class B : A { public B(string value) { Value = value; } } public class C : A { public C(string value) { Value = value; } }
Pour l'exemple disons que ce traitement c'est le remplacement d'un élément dans une liste par un autre.
Voilà le code :
Afin de factoriser le code, je ne veux créer qu'une seule méthode replace qui fasse ce traitement pour les 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 class Program { static void Main(string[] args) { List<B> listB = new List<B> { new B("B1"), new B("B2"), new B("B3") }; List<C> listC = new List<C> { new C("C1"), new C("C2"), new C("C3") }; B b = new B("B22"); C c = new C("C22"); replace(listB[1], b, listB); // les valeurs de la liste deviennent "B1", "B22", "B3" replace(listC[1], c, listC); // les valeurs de la liste deviennent "C1", "C22", "C3" } // [...] }
Pour coder cette fameuse méthode, je voulais faire ça :
Seulement avec ce code j'obtiens l'erreur de compilation suivante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 public static void replace(A oldA, A newA, List<A> listAs) { listAs.Insert(listAs.IndexOf(oldA), newA); listAs.Remove(oldA); }
Si j'ai bien compris, cela vient du fait que List<T> n'est pas covariant (alors que IEnumerable<T> l'est...).cannot convert from 'System.Collections.Generic.List<Appli.B>' to 'System.Collections.Generic.List<Appli.A>'
Cela dit, je comprends pas très bien pourquoi, surtout que j'ai réussi à m'en sortir autrement en utilisant les génériques :
J'ai donc réussi à faire ce que je voulais faire, mais sans trop comprendre pourquoi. Pour moi les deux codes sont identiques...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 public static void foo<T>(T oldA, T newA, List<T> listAs) where T : A { listAs.Insert(listAs.IndexOf(oldA), newA); listAs.Remove(oldA); }
Si quelqu'un pouvais m'éclairer.
Merci d'avance.
Partager