Pregunta

¿Cómo puedo hacer el trabajo siguiente código? Creo que no entiendo muy bien C # genéricos. Tal vez, alguien me puede apuntar en la dirección correcta.

    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 probablemente una respuesta simple.

Actualización: En primer lugar, esto no es posible en C # 3.0, pero será posible en C # 4.0.

Para ponerlo en marcha en C # 3.0, que es sólo una solución temporal hasta 4.0, utilice la siguiente:

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

        // Compiler is happy
        List<A> listC = GetCList().OfType<A>().ToList();
¿Fue útil?

Solución

siempre se puede hacer esto

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

Como "Bojan Resnik" señaló, también se puede hacer ...

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

Una diferencia a destacar es que moldeada () fallará si uno o más de los tipos no coincide. Donde OfType () devolverá un IEnumerable que contiene sólo los objetos que sean convertibles

Otros consejos

La razón de que esto no funciona es porque no puede ser determinado para estar seguro. Supongamos que tenemos

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

Y bueno, sólo hay que poner una tortuga en una lista de las jirafas, y la integridad del sistema de tipo ha sido violado. Es por eso que esto es ilegal.

La clave aquí es que los "animales" y "jirafas" se refieren al mismo objeto, y ese objeto es una lista de las jirafas. Sin embargo, una lista de las jirafas no puede hacer tanto como una lista de los animales pueden hacer; en particular, no puede contener una tortuga.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top