Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En C#, la covarianza y la contravarianza permiten la conversión de referencia implícita para los tipos de matriz, los tipos delegados y los argumentos de tipo genérico. La covarianza conserva la compatibilidad de asignaciones y la contravarianza la invierte.
En el código siguiente se muestra la diferencia entre la compatibilidad de asignaciones, la covarianza y la contravarianza.
// Assignment compatibility.
string str = "test";
// An object of a more derived type is assigned to an object of a less derived type.
object obj = str;
// Covariance.
IEnumerable<string> strings = new List<string>();
// An object that is instantiated with a more derived type argument
// is assigned to an object instantiated with a less derived type argument.
// Assignment compatibility is preserved.
IEnumerable<object> objects = strings;
// Contravariance.
// Assume that the following method is in the class:
static void SetObject(object o) { }
Action<object> actObject = SetObject;
// An object that is instantiated with a less derived type argument
// is assigned to an object instantiated with a more derived type argument.
// Assignment compatibility is reversed.
Action<string> actString = actObject;
La Covarianza para matrices permite la conversión implícita de una matriz de un tipo más derivado a una matriz de un tipo menos derivado. Pero esta operación no es segura para tipos, como se muestra en el ejemplo de código siguiente.
object[] array = new String[10];
// The following statement produces a run-time exception.
// array[0] = 10;
La compatibilidad de la covarianza y la contravarianza con grupos de métodos permite hacer coincidir firmas de método con tipos de delegado. Esto le permite asignar a delegados no solo métodos que tienen firmas coincidentes, sino también métodos que devuelven más tipos derivados (covarianza) o que aceptan parámetros que tienen tipos menos derivados (contravarianza) que los especificados por el tipo delegado. Para obtener más información, vea Varianza en delegados (C#) y Usar varianza en delegados (C#).
En el siguiente ejemplo de código se muestra el soporte de covarianza y contravarianza para los grupos de métodos.
static object GetObject() { return null; }
static void SetObject(object obj) { }
static string GetString() { return ""; }
static void SetString(string str) { }
static void Test()
{
// Covariance. A delegate specifies a return type as object,
// but you can assign a method that returns a string.
Func<object> del = GetString;
// Contravariance. A delegate specifies a parameter type as string,
// but you can assign a method that takes an object.
Action<string> del2 = SetObject;
}
En .NET Framework 4 y versiones posteriores, C# admite covarianza y contravarianza en interfaces y delegados genéricos y permite la conversión implícita de parámetros de tipo genérico. Para obtener más información, vea Varianza en interfaces genéricas (C#) y Varianza en delegados (C#).
En el ejemplo de código siguiente se muestra la conversión de referencia implícita para interfaces genéricas.
IEnumerable<String> strings = new List<String>();
IEnumerable<Object> objects = strings;
Una interfaz genérica o delegado se denomina variant si sus parámetros genéricos se declaran covariante o contravariante. C# le permite crear sus propias interfaces y delegados variantes. Para obtener más información, consulte Crear interfaces genéricas variantes (C#) y Varianza en delegados (C#).
Temas relacionados
Título | Descripción |
---|---|
Varianza en interfaces genéricas (C#) | Describe la covarianza y la contravarianza en interfaces genéricas y proporciona una lista de interfaces genéricas variantes en .NET. |
Creando interfaces genéricas variantes (C#) | Muestra cómo crear interfaces variantes personalizadas. |
Usar varianza en interfaces para colecciones genéricas (C#) | Muestra cómo la compatibilidad con covarianza y contravarianza en las interfaces IEnumerable<T> y IComparable<T> puede ayudarle a reutilizar el código. |
Varianza en delegados (C#) | Se describe la covarianza y contravarianza en delegados genéricos y no genéricos y se proporciona una lista de delegados genéricos variantes en .NET. |
Usar varianza en delegados (C#) | Se muestra cómo usar la compatibilidad de covarianza y contravarianza en los delegados no genéricos para que coincidan las firmas de método con los tipos de delegado. |
Uso de la variación para los delegados genéricos Func y Action (C#) | Se muestra cómo la compatibilidad de covarianza y contravarianza en los delegados Func y Action puede ayudarle a volver a usar el código. |