Pergunta

Por isso, com um genérico de restrição sobre o parâmetro de tipo T de classe P de "deve herdar de Um", faz a primeira chamada tiver êxito, mas a segunda chamada falhar com a conversão de tipo de erro detalhadas no comentário:

abstract class A { }

static class S
{
    public static void DoFirst(A argument) { }
    public static void DoSecond(ICollection<A> argument) { }
}

static class P<T>
    where T : A, new()
{
    static void Do()
    {
        S.DoFirst(new T());             // this call is OK

        S.DoSecond(new List<T>());      // this call won't compile with:

        /* cannot convert from 'System.Collections.Generic.List<T>'
           to 'System.Collections.Generic.ICollection<A>' */
    }
}

Não deve a restrição genérica garantir que List<T> é de fato ICollection<A>?

Foi útil?

Solução

Este é um exemplo de falta de covariância em tipos genéricos (C # 's C # faz array apoio covariância). C # 4 irá adicionar esse recurso em tipos de interface e também irá atualizar vários tipos de interface BCL para apoiá-lo também.

Por favor, veja C # 4.0: Covariância e contravariance :

Neste artigo vou tentar cobrir um dos C # 4.0 inovações. Um dos novos recursos é covariância e contravariance em parâmetros de tipo que agora é apoiada por representantes genéricos e interfaces genéricos. do primeiro deixe ver o que faz essas palavras significam:)

Outras dicas

A restrição não tem efeito sobre o problema; o problema é que você está passando uma lista em um parâmetro que requer ICollection - C # faz covariância não suporte então você precisa converter explicitamente a lista para um ICollection:

S.DoSecond((ICollection<A>) new List<T>());      // this call will be happy

Você tem rigidez de parâmetro para DoSecond como o tipo de ICollection<A>.Apesar do fato de que T é do tipo Um, em tempo de compilação não há implícito elenco de entre a Lista de<T> e ICollection<A>.Você vai precisar para criar a lista e lançá-lo aos ICollection<A> quando você chamar DoSecond, ou fazer DoSecond um método genérico em si.

NOTA:Este tipo de conversão implícita deve ser suportado em C# 4.0, o que irá proporcionar muito melhor co/contravariância sobre o que o C# 3.0 oferece.

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