Pregunta

¿Cuál es el significado de los conceptos 'covarianza' y 'contravarianza'?

Dadas 2 clases, Animal y Elephant (que hereda de Animal ), entiendo que obtendrías errores de tiempo de ejecución si intentas poner un elefante en una variedad de animales, y esto sucede porque el elefante es '' más grande '' (más específico) que Animal. Pero, ¿podría colocar un animal en un conjunto de elefantes, viendo cómo se garantiza que el elefante contenga las propiedades del animal?

¿Fue útil?

Solución

Lo tienes al revés. Puede agregar un Elefante a una matriz Animal porque es un Animal, y se garantiza que tiene todos los métodos que se requiere que tenga un Animal. No puede agregar un Animal a una matriz de Elefante porque no tiene todos los métodos que un Elefante debe tener.

El artículo de Wikipedia sobre covarianza y contravarianza tiene una buena explicación de esto:

  

Dentro del sistema de tipos de un lenguaje de programación, un operador de tipos a tipos es covariante si conserva el orden, & # 8804 ;, de tipos, que ordena tipos de más específicos a más genéricos; es contravariante si invierte este orden. Si ninguno de estos aplica, el operador es invariable. Estos términos provienen de la teoría de categorías.

Además, usted dijo que el tipo Elefante era '' más grande '', y este no es el caso. Type Animal es " más grande " en el sentido de que incluye tipos más específicos, como Elefante, Jirafa y León.

Otros consejos

Eche un vistazo a esta descripción general de covarianza y contravarianza en C # 4.0 y vea si eso ayuda:

http://blogs.msdn.com/charlie/archive/2008/10/27/linq-farm-covariance-and-contravariance-in-visual-studio-2010.aspx

Debería intentar leer las páginas 45-49 de Presentación de .NET 4.0 con Visual Studio 2010 que trata con este ejemplo exacto. Incluso tiene algunas fotos bonitas de elefantes.

El punto principal para sacar es hacer esto

var things = new List<IThing<IContent>> { new ConcreteThing() }

con:

public class ConcreteThing : IThing<ConcreteContent>
{

}

necesita el "salir" en la definición de interfaz, que permitirá establecer formularios más específicos, pero se debe garantizar que todo lo que se lea de IThing sea del tipo más general.

public interface IThing<out T> where T : IContent
{
}

 ingrese la descripción de la imagen aquí

public interface IGoOut<out T>
{
    T Func();
}
public interface IComeIn<in T>
{
    void Action(T obj);
}
public class GoOutClass<T>:IGoOut<T>
{
    public T Func()
    {
        return default(T);
    }
}

public class ComeInClass<T> : IComeIn<T>
{
    public void Action(T obj) {  }
}

==========================================================
object obj = null;
//Covariance Example [Array +  IEnumerable<T> +  IEnumerator<T>  +  IInterface<Out T>  +  Func<T>]
object[] array = (string[]) obj;
IEnumerable<object> enumerable = (IEnumerable<string>) obj;
IEnumerator<object> enumerator = (IEnumerator<string>)obj;
IGoOut<object> goOut = (GoOutClass<string>)obj;
Func<object> func = (Func<string>)obj;


//Contravariance Example[IInterface<in T>]
IComeIn<string> comeIn = (ComeInClass<object>) obj;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top