Frage

Wie kann ich den folgenden Code arbeiten? Ich glaube nicht, dass ich ziemlich C # Generika verstehen. Vielleicht kann mir jemand in die richtige Richtung zeigen.

    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);
        }
    }

Es ist wahrscheinlich eine einfache Antwort.

Update: Erstens ist dies nicht möglich, in C # 3.0, wird aber möglich sein, in C # 4.0.

, um es läuft in C # 3.0, die bis 4.0 nur eine Abhilfe ist, verwenden Sie die folgenden Schritte aus:

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

        // Compiler is happy
        List<A> listC = GetCList().OfType<A>().ToList();
War es hilfreich?

Lösung

Sie könnte dies immer tun

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

Als "Bojan Resnik" wies darauf hin, können Sie auch tun ...

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

Ein Unterschied zu beachten ist, dass Cast () schlägt fehl, wenn eine oder mehrere der Typen stimmen nicht überein. Wo OfType () eine IEnumerable Rückkehr nur die Objekte enthält, die umwandelbar sind,

Andere Tipps

Der Grund, warum dies nicht der Fall funktioniert, weil es nicht als sicher bestimmt werden kann. Angenommen, Sie haben

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());  

Und hey, man muss nur eine Schildkröte in eine Liste von Giraffen setzen, und die Art der Systemintegrität wird nun verletzt. Deshalb ist dies illegal.

Der Schlüssel hier ist, dass „Tiere“ und „Giraffen“ auf das gleiche Objekt beziehen, und das Objekt ist eine Liste der Giraffen. Aber eine Liste der Giraffen können nicht so viel wie eine Liste von Tieren tun tun können; insbesondere kann es nicht eine Schildkröte enthalten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top