2010-04-28 24 views
8

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

Respuesta

8

Si el compilador tiene formas de inferir lo que son usos válidos tanto para la covarianza (fuera) y contravarianza (en), ¿por qué tenemos que marcar interfaces como tales?

No estoy muy seguro de entender la pregunta. Creo que estás preguntando dos cosas.

1) ¿Puede el compilador deducir las anotaciones de varianza?

y

2) ¿Por qué C# no admite variación llamar in situ como Java hace?

La respuesta a la primera es:

interface IRezrov<V, W> 
{ 
    IRezrov<V, W> Rezrov(IRezrov<W, V> x); 
} 

invito a intentar deducir lo que todas las posibles anotaciones de varianza legales están en V y W. Es posible obtener una sorpresa.

Si no puede encontrar una mejor anotación única de varianza para este método, ¿por qué cree que puede hacerlo el compilador?

Más razones aquí:

http://blogs.msdn.com/ericlippert/archive/2007/10/29/covariance-and-contravariance-in-c-part-seven-why-do-we-need-a-syntax-at-all.aspx

De manera más general: Su pregunta indica un razonamiento falaz. La capacidad de comprobar de forma económica si una solución es correcta no implica lógicamente que haya una forma económica de encontrar una solución correcta. Por ejemplo, una computadora puede verificar fácilmente si p * q == r es verdadero o falso para los números primos p de dos mil dígitos. Eso no implica que sea fácil tomar r y encontrar pyq de tal manera que se satisfaga la igualdad.El compilador puede verificar fácilmente si una anotación de varianza es correcta o incorrecta; eso no significa que pueda encontrar una anotación de variación correcta entre los posibles miles de millones de anotaciones posibles.

La respuesta a la segunda es: C# no es Java.

+0

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

+1

@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. –

+0

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. –

0

OK, aquí está la respuesta a lo que pedí (a partir de la respuesta de Eric): http://blogs.msdn.com/ericlippert/archive/2007/10/29/covariance-and-contravariance-in-c-part-seven-why-do-we-need-a-syntax-at-all.aspx

En primer lugar, me parece que la varianza debe ser algo que diseñar deliberadamente en su interfaz de o delegar. Hacerlo simplemente comienza a suceder sin control por parte del usuario que funciona en contra de ese objetivo, y también puede introducir cambios bruscos. (Más en los que en un post más adelante!)

Si lo hace, significa también que automagicamente como el proceso de desarrollo sigue y se añaden métodos de las interfaces, la varianza de la interfaz puede cambiar de forma inesperada . Esto podría introducir cambios inesperados y de largo alcance en otro lugar del programa.

Decidí ponerlo aquí explícitamente porque aunque su enlace tiene la respuesta a mi pregunta, la publicación en sí no lo hace.

Cuestiones relacionadas