Cuando definimos nuestras interfaces en C# 4.0, podemos marcar cada uno de los parámetros genéricos como in
o out
. Si tratamos de establecer un parámetro genérico como out y eso llevaría a un problema, el compilador genera un error que no nos permite hacer eso.Inferencia de covarianza y contradicción en C# 4.0
Pregunta:
Si el compilador tiene formas de inferir lo que son usos válidos tanto para covariance
(out
) y contravariance
(in
), ¿por qué tenemos que marcar interfaces como tales? ¿No sería suficiente simplemente dejarnos definir las interfaces como siempre lo hicimos, y cuando tratamos de usarlas en nuestro código de cliente, generar un error si tratamos de usarlas de una manera no segura?
Ejemplo:
interface MyInterface<out T> {
T abracadabra();
}
//works OK
interface MyInterface2<in T> {
T abracadabra();
}
//compiler raises an error.
//This makes me think that the compiler is cappable
//of understanding what situations might generate
//run-time problems and then prohibits them.
Además,
no es lo que hace de Java en la misma situación? Por lo que recuerdo, usted simplemente hace algo como
IMyInterface<? extends whatever> myInterface; //covariance
IMyInterface<? super whatever> myInterface2; //contravariance
¿O estoy mezclando cosas?
Gracias
Creo que su segunda pregunta se parecía más a "¿En qué se diferencian las anotaciones de varianza de C# de los tipos de comodines de Java?" – Gabe
@Gabe: C# no * varianza del sitio de declaración *. Java no hace * call-site * varianza. La varianza del sitio de llamadas es una idea interesante, pero me parece extraño tener un tipo de variante según cómo se usa en un sitio en particular, en lugar de cómo se define para comportarse. –
Sí, ahora entiendo cuál es el problema con el uso de Java. Tiene la ventaja de no tener que indicar los parámetros de la interfaz como entrantes o salientes, pero entonces algunos clientes podrían darle algún uso ahora que luego no se superará si planeo actualizar mi interfaz. –