Share via


Covariância e/contravariância (C# e Visual Basic)

C# e Visual Basic, covariância e/contravariância Habilitar conversão de referência implícita para tipos de matriz, tipos delegate e argumentos de tipo genérico. Covariância preserva a compatibilidade de atribuição e/contravariância inverte a ele.

O código a seguir demonstra a diferença entre a compatibilidade de atribuição e covariância/contravariância.

' Assignment compatibility. 
Dim str As String = "test"
' An object of a more derived type is assigned to an object of a less derived type. 
Dim obj As Object = str

' Covariance. 
Dim strings As IEnumerable(Of String) = New List(Of 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. 
Dim objects As IEnumerable(Of Object) = strings

' Contravariance.           
' Assume that there is the following method in the class: 
' Shared Sub SetObject(ByVal o As Object)
' End Sub
Dim actObject As Action(Of Object) = AddressOf 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. 
Dim actString As Action(Of String) = actObject
// 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;

Covariância para arrays permite a conversão implícita de uma matriz de um tipo mais derivado para uma matriz de um tipo derivado de menos. Mas esta operação não é tipo seguro, como mostrado no exemplo de código a seguir.

Dim array() As Object = New String(10) {}
' The following statement produces a run-time exception.
' array(0) = 10
object[] array = new String[10];
// The following statement produces a run-time exception.
// array[0] = 10;

Suporte a covariância e/contravariância grupos de método permite assinaturas de método de correspondência com os tipos de representante. Isso permite que você atribuir aos delegados, não apenas os métodos que possuem a correspondência de assinaturas, mas também métodos que retornam mais derivado tipos (covariância) ou que aceite parâmetros que têm menos tipos derivados (/ contravariância) do que o especificado pelo tipo delegate. Para obter mais informações, consulte Variação de delegados (C# e Visual Basic) e Usando a variação delegados (C# e Visual Basic).

O exemplo de código a seguir mostra a covariância e/contravariância suportam para grupos de método.

Shared Function GetObject() As Object
    Return Nothing
End Function

Shared Sub SetObject(ByVal obj As Object)
End Sub

Shared Function GetString() As String
    Return ""
End Function

Shared Sub SetString(ByVal str As String)

End Sub

Shared Sub Test()
    ' Covariance. A delegate specifies a return type as object,
    ' but you can assign a method that returns a string.
    Dim del As Func(Of Object) = AddressOf GetString

    ' Contravariance. A delegate specifies a parameter type as string,
    ' but you can assign a method that takes an object.
    Dim del2 As Action(Of String) = AddressOf SetObject
End Sub
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 2010, C# e Visual Basic de Visual Studio suportam a covariância e/contravariância no delegados e interfaces genéricas e permitem 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 Visual Basic) e Variação de delegados (C# e Visual Basic).

O exemplo de código a seguir mostra a conversão de referência implícita para interfaces genéricas.

Dim strings As IEnumerable(Of String) = New List(Of String)
Dim objects As IEnumerable(Of Object) = strings
IEnumerable<String> strings = new List<String>();
IEnumerable<Object> objects = strings;

Uma interface genérica ou delegado é chamado de variante se os seus parâmetros genéricos são declarados covariant ou contravariant. C# e Visual Basic permitem que você crie seus próprios delegados e interfaces variant. Para obter mais informações, consulte Criando Interfaces genéricas de variante (C# e Visual Basic) e Variação de delegados (C# e Visual Basic).

Tópicos relacionados

Título

Descrição

Variação em Interfaces genéricas (C# e Visual Basic)

Discute a covariância e/contravariância no interfaces genéricas e fornece uma lista de interfaces genéricas variant a.NET Framework.

Criando Interfaces genéricas de variante (C# e Visual Basic)

Mostra como criar interfaces personalizadas de variant.

Usando a variação nas Interfaces de coleções genéricas (C# e Visual Basic)

Mostra como covariância/contravariância suporte a e na IEnumerable<T> e IComparable<T> interfaces podem ajudar você a reutilizar o código.

Variação de delegados (C# e Visual Basic)

Discute a covariância e/contravariância delegados genérico e não genéricas e fornece uma lista de variant representantes genéricos na.NET Framework.

Usando a variação delegados (C# e Visual Basic)

Mostra como usar o suporte a covariância e/contravariância no não-genéricas delegados para coincidir com as assinaturas de método com tipos delegate.

Usando a variação para representantes genéricos Func e ação (C# e Visual Basic)

Mostra como covariância/contravariância suporte a e na Func e Action delegados podem ajudar você a reutilizar o código.