Posso ter um tipo que seja covariante e contravariante, ou seja, totalmente fungível/mutável com os tipos sub e super?
-
25-09-2019 - |
Pergunta
Posso ter um tipo (por enquanto esquece sua semântica) que pode ser covariante e contravariante?
por exemplo:
public interface Foo<in out T>
{
void DoFooWith(T arg);
}
Fora para o blog de Eric Lippert para a carne e as batatas de variância no C# 4.0, pois há pouco mais em qualquer lugar que cobre um terreno adequado sobre o assunto.
Eu tentei de qualquer maneira, não apenas não permite isso, mas me diz que estou perdendo o ponto principal. Preciso entender o link entre somente leitura, somente de gravação e variação.
Acho que tenho mais um pouco de leitura para fazer.
Mas quaisquer respostas curtas e indutoras de epifania são bem -vindas.
Solução
Não, você não pode fazer isso.
Suponha que isso fosse legal. Você faz um IFoo<Giraffe>
. Como o ifoo é covariante em t, você pode convertê -lo por meio de conversão de referência do TypeAfe IFoo<object>
. Por ser contravariante, você pode converter isso para IFoo<Banana>
. Para que possível semântica existem IFoo<T>
de modo que faz sentido ser capaz de converter um IFOO de girafas em um IFOO de bananas por conversão de referência? Girafas e bananas não têm nada em comum além de serem tipos de referência. Você não pode ter um método em IFoo<Banana>
Isso retorna uma banana, porque pode ser uma implementação de IFoo<Giraffe>
; Como o autor da implementação saberia distribuir uma banana? Você não pode ter um método em IFoo<Banana>
Isso leva uma banana pelo mesmo motivo; o implementador de IFoo<Giraffe>
está esperando que você entregue a ele uma girafa.
Aqui está outra maneira de olhar para ele:
- "em t" significa (aproximadamente) "t aparece apenas em posições de entrada".
- "Out t" significa (aproximadamente) "t aparece apenas nas posições de saída".
Portanto, "em fora t" significaria ... o que? Como já vimos, isso só pode significar "T não aparece em nenhum método ou propriedade". Qual é o sentido de fazer um tipo genérico em T onde você nunca usa t?