Kovarianz und Kontravarianz (C# und Visual Basic)

In C# und Visual Basic ermöglichen Kovarianz und Kontravarianz implizite Verweiskonvertierung für Arraytypen, Delegattypen und generische Typargumente. Durch Kovarianz bleibt die Zuweisungskompatibilität erhalten, und durch Kontravarianz wird sie rückgängig gemacht.

Der folgende Code veranschaulicht den Unterschied zwischen Zuweisungskompatibilität, Kovarianz und Kontravarianz.

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

Kovarianz für Arrays ermöglicht die implizite Konvertierung eines Arrays eines stärker abgeleiteten Typs in ein Array eines weniger stark abgeleiteten Typs. Diese Vorgänge sind jedoch nicht typsicher, wie im folgenden Codebeispiel gezeigt.

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;

Die Unterstützung von Kovarianz und Kontravarianz für Methodengruppen ermöglicht den Abgleich von Methodensignaturen mit Delegattypen. Dies bedeutet, dass Sie Delegaten nicht nur Methoden zuweisen können, die über übereinstimmende Signaturen verfügen, sondern auch Methoden, die stärker abgeleitete Typen (Kovarianz) zurückgeben oder Parameter annehmen, die weniger stark abgeleitete Typen (Kontravarianz) aufweisen, als vom Delegattyp angegeben wurde. Weitere Informationen finden Sie unter Varianz in Delegaten (C# und Visual Basic) und Verwenden von Varianz in Delegaten (C# und Visual Basic).

Im folgenden Codebeispiel wird die Unterstützung von Kovarianz und Kontravarianz für Methodengruppen veranschaulicht.

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 und Visual Studio 2010 unterstützt C# ebenso wie Visual Basic Ko- und Kontravarianz in generischen Schnittstellen und Delegaten; außerdem wird in beiden Fällen eine implizite Konvertierung von generischen Typparametern ermöglicht. Weitere Informationen finden Sie unter Varianz in generischen Schnittstellen (C# und Visual Basic) und Varianz in Delegaten (C# und Visual Basic).

Im folgenden Codebeispiel wird die implizite Verweiskonvertierung für generische Schnittstellen veranschaulicht.

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;

Eine generische Schnittstelle oder ein generischer Delegat werden als variant bezeichnet, wenn die zugehörigen generischen Parameter als Ko- oder Kontravariante deklariert werden. Sowohl in C# als auch in Visual Basic können Sie eigene variante Schnittstellen und Delegaten erstellen. Weitere Informationen finden Sie unter Erstellen varianter generischer Schnittstellen (C# und Visual Basic) und Varianz in Delegaten (C# und Visual Basic).

Verwandte Themen

Titel

Beschreibung

Varianz in generischen Schnittstellen (C# und Visual Basic)

Erläutert Kovarianz und Kontravarianz in generischen Schnittstellen und stellt eine Liste varianter generischer Schnittstellen in .NET Framework bereit.

Erstellen varianter generischer Schnittstellen (C# und Visual Basic)

Zeigt, wie benutzerdefinierte variante Schnittstellen erstellt werden.

Verwenden von Varianz in Schnittstellen für generische Auflistungen (C# und Visual Basic)

Zeigt an, wie die Ko- und Kontravarianzunterstützung in der IEnumerable<T>-Schnittstelle und in der IComparable<T>-Schnittstelle die Wiederverwendung von Code erleichtert.

Varianz in Delegaten (C# und Visual Basic)

Erläutert Ko- und Kontravarianz in generischen und nicht generischen Delegaten und stellt eine Liste varianter generischer Delegaten in .NET Framework bereit.

Verwenden von Varianz in Delegaten (C# und Visual Basic)

Zeigt, wie die Ko- und Kontravarianzunterstützung in nicht generischen Delegaten verwendet wird, um Methodensignaturen und Delegattypen zu vergleichen.

Verwenden von Varianz für die generischen Delegaten Func und Action (C# und Visual Basic)

Zeigt an, wie die Ko- und Kontravarianzunterstützung im Func-Delegaten und im Action-Delegaten die Wiederverwendung von Code erleichtert.