Condividi tramite


Covarianza e controvarianza (C# e Visual Basic)

In C# e in Visual Basic, la covarianza e la controvarianza permettono alla conversione dei riferimenti implicita per i tipi di matrice, i tipi delegati e gli argomenti di tipo generico. La covarianza conserva la compatibilità di assegnazione e la controvarianza la inverte.

Il dimostra seguente la differenza fra la compatibilità di assegnazione, la covarianza e la controvarianza.

' 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;

La covarianza per le matrici permette la conversione implicita di una matrice di tipo più derivato in una matrice di tipo meno derivato. Ma tali operazioni non sono indipendenti dai tipi, come mostrato nel seguente esempio di codice.

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;

Il supporto di covarianza e controvarianza per i gruppi di metodi consentono la corrispondenza delle firme di metodo con i tipi delegati. In questo modo è possibile assegnare ai delegati non solo metodi con firme corrispondenti, ma anche metodi che restituiscono tipi più derivati (covarianza) o che accettano parametri con tipi meno derivati (controvarianza) di quello specificato dal tipo delegato. Per ulteriori informazioni, vedere Varianza nei delegati (C# e Visual Basic) e Utilizzo della varianza nei delegati (C# e Visual Basic).

Il seguente esempio di codice mostra il supporto di covarianza e controvarianza per i gruppi di metodi.

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;
}

In .NET Framework 4 e Visual Studio 2010, sia C# che Visual Basic supportano la covarianza e la controvarianza in interfacce e delegati generici e consentono la conversione implicita di parametri di tipo generico. Per ulteriori informazioni, vedere Varianza nelle interfacce generiche (C# e Visual Basic) e Varianza nei delegati (C# e Visual Basic).

Il seguente esempio di codice mostra la conversione dei riferimenti implicita per le interfacce generiche.

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;

Un'interfaccia o delegato generico è detto variant se i parametri generici vengono dichiarati covarianti o controvarianti. Sia C# che Visual Basic consentono di creare interfacce e delegati variant personalizzati. Per ulteriori informazioni, vedere Creazione di interfacce generiche variant (C# e Visual Basic) e Varianza nei delegati (C# e Visual Basic).

Argomenti correlati

Titolo

Descrizione

Varianza nelle interfacce generiche (C# e Visual Basic)

Vengono illustrate la covarianza e la controvarianza nelle interfacce generiche e viene fornito un elenco di varie interfacce generiche in .NET Framework.

Creazione di interfacce generiche variant (C# e Visual Basic)

Viene illustrato come creare interfacce variant personalizzate.

Utilizzo della varianza nelle interfacce per gli insiemi generici (C# e Visual Basic)

Viene illustrato come il supporto della covarianza e della controvarianza nelle interfacce IEnumerable<T> e IComparable<T> consente di riutilizzare il codice.

Varianza nei delegati (C# e Visual Basic)

Vengono illustrate la covarianza e la controvarianza nei delegati generici e non generici e viene fornito un elenco di vari delegati generici in .NET Framework.

Utilizzo della varianza nei delegati (C# e Visual Basic)

Viene illustrato come utilizzare il supporto della covarianza e della controvarianza nei delegati non generici per la corrispondenza delle firme di metodo con i tipi delegati.

Utilizzo della varianza per i delegati generici Func e Action (C# e Visual Basic)

Viene illustrato come il supporto della covarianza e della controvarianza nei delegati Func e Action consente di riutilizzare il codice.