Pergunta

herda tudo, desde objeto. É a base da herança. Tudo pode ser convertido implicitamente a árvore de herança, ou seja.

object me = new Person();

Portanto, seguindo este até à sua conclusão lógica, um grupo de pessoas também seria um grupo de objetos:

List<Person> people = new List<Person>();
people.Add(me);
people.Add(you);
List<object> things = people; // Ooops.

Exceto, que não vai funcionar, as pessoas que projetaram .NET seja esquecido isso, ou há uma razão, e eu não tenho certeza de qual. Pelo menos uma vez eu tenho que correr em uma situação onde isso teria sido útil, mas eu tinha que acabar usando um truque desagradável (subclasse Lista apenas para implementar um operador de conversão).

A questão é esta: existe uma razão para este comportamento? Existe uma solução mais simples para obter o comportamento desejado?

Para o registro, eu acredito que a situação que eu queria que este tipo de comportamento era uma função de impressão genérico que exibida listas de objetos chamando ToString () e formatar as cordas bem.

Foi útil?

Solução

OK, todo mundo que usou genéricos no .net deve ter executar para esse em um ponto ou outro.

Sim, intuitivamente ele deve funcionar. Não, na versão atual do compilador C # isso não acontece.

Eric Lippert tem uma boa explicação sobre esta questão (é em onze partes ou alguma coisa e vai dobrar se importa em alguns lugares, mas é bem vale a pena ler). Consulte aqui .

edit:

cavado um outro link relevante, este discute como Java lida com isso. Consulte aqui

Outras dicas

Você pode usar o LINQ para lançá-lo:

IEnumerable<Person> oldList = someIenumarable;
IEnumerable<object> newList = oldlist.Cast<object>()

À primeira vista, isso não faz sentido intuitivo. Mas ele faz. Olhar para este código:

List<Person> people = new List<Person>();
List<object> things = people; // this is not allowed
// ...
Mouse gerald = new Mouse();
things.add(gerald);

Agora, de repente tem um List de objetos Person ... com um Mouse dentro dela!

Isso explica por que a atribuição de um objeto do tipo A<T> a uma variável do tipo A<S> não é permitido, mesmo se S é um supertipo de T.

A solução LINQ é uma boa. Outra solução, uma vez que você estiver usando o tipo de objeto, é passar a lista como IEnumerable (não a versão genérica).

Editar : C # 4 (atualmente beta) suporta um parâmetro de tipo covariant em IEnumerable. Enquanto você não vai ser capaz de atribuir diretamente a um List , você pode passar a sua lista para um método espera um IEnumerable .

Enquanto que o seu tentando, de fato, o fluxo logicamente, a sua realmente uma característica que muitas línguas não suportam nativamente. Isto é o que é chamado co / variância contra, que tem a ver com quando e como os objetos podem ser implicitamente lançado de um lado para nother por um compilador. Felizmente, C # 4.0 trará covariância e contravariance ao C # arena, e tais moldes implícitas como isso deve ser possível.

Para uma explicação detalhada deste, o seguinte vídeo Channel9 deve ser útil:

http://channel9.msdn.com/shows/Going+Deep/Inside-C-40-dynamic-type-optional-parameters-more-COM-friendly/

Com os métodos de extensão LINQ você pode fazer

IEnumerable<object> things = people.Cast<object>();
List<object> things = people.Cast<object>().ToList();

Caso contrário, desde que você está digitando fortemente a lista a conversão implícita não é permitido.

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