¿Por qué necesitamos nuevas palabras clave para Covarianza y Contravarianza en C#?
-
06-07-2019 - |
Pregunta
Puede alguien explicar por qué existe la necesidad de agregar una o parámetro para indicar que un tipo genérico es Co o Contra variante en C# 4.0?
He estado tratando de entender por qué esto es importante y por qué el compilador no puede entenderlo..
Gracias,
Josh
Solución
Eric Lippert, que trabaja en el idioma, tiene una serie de publicaciones en msdn que deberían ayudar a aclarar los problemas involucrados:
http://blogs.msdn.com/ericlippert/ archive / tags / Covarianza + y + Contravarianza / default.aspx
Al leer los artículos que se muestran en ese enlace, comience en la parte inferior y continúe.
Eventualmente llegarás a # 7 (¿Por qué necesitamos una sintaxis?) .
Otros consejos
Que en realidad no necesidad de ellos, más necesitamos abstract
en las clases o en ambos out
y ref
.Existen sólo para que nosotros, como programadores, puede hacer que nuestra intención clara de cristal, por lo que el mantenimiento programador de saber lo que estamos haciendo, y el compilador puede comprobar que estamos haciendo lo correcto.
Así, el principal problema es que si usted tiene una jerarquía de clases como:
class Foo { .. }
class Bar : Foo { .. }
Y usted tiene un IEnumerator<Bar>
, usted no puede usar eso como una IEnumerator<Foo>
aunque eso sería perfectamente seguro.En 3.5, esto obliga a un gran número de dolorosos giros.Esta operación siempre estaría a salvo, pero es rechazada por el tipo de sistema, ya que no sabe acerca de la covariante utilizar el parámetro de tipo genérico. IEnumerator<Bar>
sólo puede devolver un Bar
y cada una de las Bar
es un Foo
.
Del mismo modo, si usted tuvo una IEqualityComparer<Foo>
puede ser utilizado para comparar cualquier par de objetos de tipo Foo
incluso si uno o ambos, es una Bar
, pero no se puede convertir en un IEqualityComparer<Bar>
porque no sabe acerca de la contravariante utilizar el parámetro de tipo genérico. IEqualityComparer<Foo>
sólo consume objetos de tipo Foo
y cada una de las Bar
es un Foo
.
Sin estas palabras clave que estamos obligados a asumir el genérico argumento puede ocurrir como un argumento a un método y como el tipo de resultado de un método, y por tanto, no podemos permitir con seguridad que cualquiera de los de arriba conversiones.
Con ellos, el tipo de sistema es gratuito y nos permitirá de forma segura upcast y abatido entre los interfaces en la dirección indicada por la palabra clave y obtener errores que indican a la hora de violar la disciplina necesaria para garantizar que la seguridad.
El in
y out
palabras clave han sido las palabras clave, ya que C# 1.0, y han sido utilizadas en el contexto de in
- y out
- parámetros de los métodos.
Covarianza y contravarianza son restricciones sobre cómo se puede implementar una interfaz.No hay una buena manera para inferir de ellos - la única manera, creo yo, es a partir del uso, y que sería complicado y al final no iba a funcionar.
Jon y Joel proporcionaron una respuesta bastante completa a esto, pero la conclusión es que el compilador no los necesita tanto sino que ayudan a garantizar la seguridad de la implementación indicando explícitamente La varianza del parámetro. Esto sigue un patrón muy similar a requerir la palabra clave out
o ref
tanto en el sitio de llamada como en el sitio de declaración.