Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
No C#, a covariância e a contravariância habilitam a conversão de referência implícita para tipos de matriz, tipos de delegados e argumentos de tipo genérico. A covariância preserva a compatibilidade de atribuição e a contravariância a reverte.
O código a seguir demonstra a diferença entre compatibilidade de atribuição, covariância e contravariância.
// 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;
A covariância para matrizes permite a conversão implícita de uma matriz de um tipo mais derivado em uma matriz de um tipo menos derivado. Mas essa operação não é tipo seguro, conforme mostrado no exemplo de código a seguir.
object[] array = new String[10];
// The following statement produces a run-time exception.
// array[0] = 10;
O suporte de covariância e contravariância aos grupos de método permite a correspondência de assinaturas de método com tipos de delegados. Isso permite atribuir aos delegados não apenas métodos que têm assinaturas correspondentes, mas também métodos que retornam tipos mais derivados (covariância) ou que aceitam parâmetros que têm tipos menos derivados (contravariância) do que os especificados pelo tipo delegado. Para obter mais informações, consulte Variação em Delegados (C#) e Uso da Variação em Delegados (C#).
O exemplo de código a seguir mostra o suporte a covariância e contravariância para 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;
}
No .NET Framework 4 e versões posteriores, o C# dá suporte a covariância e contravariância em interfaces e delegados genéricos e permite a conversão implícita de parâmetros de tipo genérico. Para obter mais informações, consulte Variação em Interfaces Genéricas (C#) e Variação em Delegados (C#).
O exemplo de código a seguir mostra a conversão de referência implícita para interfaces genéricas.
IEnumerable<String> strings = new List<String>();
IEnumerable<Object> objects = strings;
Uma interface ou delegado genérico é chamado de variante se seus parâmetros genéricos forem declarados covariantes ou contravariantes. O C# permite que você crie suas próprias interfaces e delegados personalizados. Para obter mais informações, consulte Criando interfaces genéricas variantes (C#) e Variação em delegados (C#).
Tópicos relacionados
Título | Descrição |
---|---|
Variação em interfaces genéricas (C#) | Discute covariância e contravariância em interfaces genéricas e fornece uma lista de interfaces genéricas variantes no .NET. |
Criando interfaces genéricas variantes (C#) | Mostra como criar interfaces variantes personalizadas. |
Usando variação em interfaces para coleções genéricas (C#) | Mostra como o suporte à covariância e à contravariância nas interfaces IEnumerable<T> e IComparable<T> pode ajudá-lo a reutilizar o código. |
Variação em delegados (C#) | Discute a covariância e a contravariância em interfaces genéricas e não genéricas, e fornece uma lista de delegados genéricos variáveis no .NET. |
Usando variação em delegados (C#) | Mostra como usar o suporte de covariância e contravariância em delegados não genéricos para corresponder às assinaturas de método com tipos delegados. |
Usar variação para delegados genéricos Func e Action (C#) | Mostra como o suporte de covariância e contravariância nos delegados Func e Action pode ajudar na reutilização do código. |