Pergunta

Como posso fazer o seguinte código de trabalho? Eu não acho que eu entendo muito bem C # genéricos. Talvez, alguém pode me apontar na direção certa.

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

É provavelmente uma resposta simples.

Update: Em primeiro lugar, isso não é possível em C # 3.0, mas será possível em C # 4.0.

Para obtê-lo correr em C # 3.0, que é apenas uma solução temporária até 4.0, use o seguinte:

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

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

Solução

você sempre pode fazer isso

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

Como "Bojan Resnik" apontou, você também pode fazer ...

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

A diferença a notar é que Elenco () irá falhar se um ou mais dos tipos não corresponde. Onde OfType () irá retornar um IEnumerable contendo apenas os objetos que são conversíveis

Outras dicas

A razão isso não funcionar é porque ele não pode ser determinado para ser seguro. Suponha que você tenha

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

E hey, você acabou de colocar uma tartaruga em uma lista de girafas, e a integridade do sistema tipo já foi violada. É por isso que esta é ilegal.

A chave aqui é que "animais" e "girafas" referem-se ao mesmo objeto e esse objeto é uma lista de girafas. Mas uma lista de girafas não pode fazer tanto quanto uma lista de animais pode fazer; em particular, não podem conter uma tartaruga.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top