Question

Comment puis-je faire fonctionner le code suivant? Je ne pense pas que je comprends tout à fait génériques C #. Peut-être, quelqu'un peut me diriger dans la bonne direction.

    public abstract class A
    {
    }

    public class B : A
    {
    }

    public class C : A
    {
    }

    public static List<C> GetCList()
    {
        return new List<C>();
    }

    static void Main(string[] args)
    {
        List<A> listA = new List<A>();

        listA.Add(new B());
        listA.Add(new C());

        // Compiler cannot implicitly convert
        List<A> listB = new List<B>();

        // Compiler cannot implicitly convert
        List<A> listC = GetCList();

        // However, copying each element is fine
        // It has something to do with generics (I think)
        List<B> listD = new List<B>();
        foreach (B b in listD)
        {
            listB.Add(b);
        }
    }

Il est probablement une réponse simple.

Mise à jour: Tout d'abord, cela est impossible en C # 3.0, mais sera possible en C # 4.0.

Pour le faire fonctionner en C # 3.0, qui est juste une solution de contournement jusqu'à 4.0, utilisez ce qui suit:

        // Compiler is happy
        List<A> listB = new List<B>().OfType<A>().ToList();

        // Compiler is happy
        List<A> listC = GetCList().OfType<A>().ToList();
Était-ce utile?

La solution

vous pouvez toujours le faire

List<A> testme = new List<B>().OfType<A>().ToList();

"Bojan Resnik" a souligné, vous pouvez aussi le faire ...

List<A> testme = new List<B>().Cast<A>().ToList();

Une différence à noter est que Cast () échouera si un ou plusieurs des types ne correspond pas. Lorsque OfType () retourne un IEnumerable contenant uniquement les objets qui sont convertibles

Autres conseils

La raison pour laquelle cela ne fonctionne pas est parce qu'il ne peut pas être déterminé à être en sécurité. Supposons que vous avez

List<Giraffe> giraffes = new List<Giraffe>();
List<Animal> animals = giraffes; // suppose this were legal.
// animals is now a reference to a list of giraffes, 
// but the type system doesn't know that.
// You can put a turtle into a list of animals...
animals.Add(new Turtle());  

hey, vous mettez juste une tortue dans une liste des girafes, et l'intégrité du système de type a maintenant été violé. Voilà pourquoi cela est illégal.

La clé ici est que les « animaux » et « girafes » font référence au même objet, et cet objet est une liste des girafes. Mais la liste des girafes ne peut pas faire autant que la liste des animaux peuvent faire; en particulier, il ne peut pas contenir une tortue.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top