2012-02-19 13 views
41

Es posible en C# para añadir una anotación varianza de tipo de parámetro, forzado a tomar el tipo de valor:C# varianza anotación de un parámetro de tipo, forzado a tomar el tipo de valor

interface IFoo<in T> where T : struct 
{ 
    void Boo(T x); 
} 

¿Por qué se permite que esta por el compilador si la varianza anotación no tiene sentido en una situación como esa?

+1

¿Lo permite el compilador sin la interfaz? Recuerde que las interfaces son tipos de referencia, y cuando tiene una referencia a una estructura (como una interfaz) se encasilla automáticamente ... – MattDavey

+1

@MattDavey, sin restricción de interfaz también compila bien. Las conversiones covariantes/contravariantes requieren una representación uniforme de los tipos de origen y destino, y 'IFoo ' y 'IFoo ' se representan de manera diferente, por lo que no existe conversión. – ControlFlow

+1

Ok, disculpe la estúpida pregunta, pero ¿alguien puede explicarme por qué en el código anterior la anotación de varianza no tiene sentido? – Tudor

Respuesta

36

¿Por qué esto es permitido por el compilador ya que la anotación de la varianza no tiene ningún sentido en una situación como esta?

Está permitido por el compilador porque nunca pensé que alguien podría intentar hacer eso cuando agregué las reglas de varianza al compilador C# 4.0.

advertencias y errores del compilador son características, y con el fin de una función a implementar, se tiene que, en un mínimo, ser idea de en algún momento antes de enviar su compilador. No lo hice y, por lo tanto, nunca tuve la oportunidad de debatir siquiera si debería haber una advertencia para tal situación.

Ahora que me ha llamado la atención, la pregunta es: ¿debería ser una característica? ¿Debería el compilador producir una advertencia (o error) para este caso?

Esa es una llamada de juicio. Varias cosas que consideraríamos son:

  • ¿El código es el tipo de cosa que alguien podría tipear pensando que hace algo sensato? Uno espera no; uno espera que el desarrollador que sabe lo suficiente sobre el sistema de tipos para hacer una variante de interfaz también sepa que la varianza solo funciona en los tipos de referencia. Pero tal vez haya desarrolladores por ahí que puedan escribir esto al pensar que funcionará. No parece más allá de plausibilidad al menos. No está claramente ideado.

  • ¿El código es claramente incorrecto? Sí, probablemente sí. Parece muy poco probable que alguien quiera deliberadamente escribir una interfaz que parezca variante, pero que de hecho no lo es.

Y así sucesivamente.

Tendré que pensarlo más, pero a primera vista parece que esta podría ser una advertencia decente para agregar al compilador. Lo discutiré con el equipo y consideraremos agregarlo a la versión de Roslyn.

¡Gracias por la idea!

+2

¡Gracias por la respuesta, Eric! – ControlFlow

+0

¡Ja! Lo primero que pensé cuando leí la pregunta fue "probablemente nadie pensó en ello, esperemos y veamos lo que Eric tiene que decir". Ahora me gustaría haberme tomado el tiempo para agregar un comentario :) Añadiría que frecuentemente me encuentro utilizando la covarianza en un parámetro de tipo genérico y obteniendo advertencias; Todavía estoy en la etapa en la que me toma 30 o 60 segundos antes de recordar que necesito agregar la restricción 'clase' para eso. Entonces, un mensaje más específico sobre el error del compilador ("¿Olvidaste agregar la restricción de clase?" O algo por el estilo) me ayudaría a mí, y probablemente a otros también. – phoog

+0

Eric, ¡siempre eres honesto! Además de ser conocedor. :) – nawfal

2

Está permitido simplemente porque es código legal. No hay absolutamente ningún daño en eso. Sí, no puede usar la conversión contravariante, pero no veo el problema. Nada en el código en realidad será engañoso u ocultará algunos retorcidos gotcha.

Simplemente pienso que el compilador no comprueba si T es un valor de tipo o un tipo de referencia en la comprobación de la validez de la varianza. Es lógico que el equipo de C# supusiera que cualquiera que use la varianza de la interfaz genérica sabrá que hacerlo con los tipos de valor no tiene sentido y, en cualquier caso, no tiene efectos secundarios.

Cuestiones relacionadas