Kovarianz und Kontravarianz (C#)

Kovarianz und Kontravarianz in C# ermöglichen die implizite Referenzkonvertierung für Arraytypen, Delegattypen und generische Typargumente. Die Kovarianz behält die Zuweisungskompatibilität bei und die Kontravarianz kehrt sie um.

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

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

Die Kovarianz für Arrays ermöglicht die implizite Konvertierung eines Arrays mit einem stärker abgeleiteten Typ zu einem Array mit einem schwächer abgeleiteten Typ. Dieser Vorgang ist jedoch nicht typsicher, wie im folgenden Codebeispiel gezeigt wird.

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 es, Methodensignaturen mit Delegattypen abzugleichen. Das bedeutet, dass Sie Delegaten nicht nur Methoden mit übereinstimmenden Signaturen zuweisen können, sondern auch Methoden, die mehrere abgeleitete Typen zurückgeben (Kovarianz) oder die Parameter akzeptieren, die über weniger abgeleitete Typen verfügen, als durch den Delegattyp angegeben wurde (Kontravarianz). Weitere Informationen finden Sie unter Variance in Delegates (C#) (Varianz in Delegaten (C#)) und Using Variance in Delegates (C#) (Verwenden von Varianz in Delegaten (C#)).

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

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 oder höher unterstützt C# die Kovarianz und Kontravarianz in generischen Schnittstellen und Delegaten und ermöglicht die implizite Konvertierung von generischen Typparametern. Weitere Informationen finden Sie unter Variance in Generic Interfaces (C#) (Varianz in generischen Schnittstellen (C#)) und Variance in Delegates (C#) (Varianz in Delegaten (C#)).

Das folgende Codebeispiel zeigt die implizite Verweiskonvertierung bei generischen Schnittstellen.

IEnumerable<String> strings = new List<String>();  
IEnumerable<Object> objects = strings;  

Generische Schnittstellen oder Delegate werden als variant bezeichnet, wenn deren generische Parameter als kovariant oder kontravariant deklariert sind. C# ermöglicht es Ihnen, eigene variante Schnittstellen oder Delegate zu erstellen. Weitere Informationen finden Sie unter Creating Variant Generic Interfaces (C#) (Erstellen von varianten generischen Schnittstellen (C#)) und Variance in Delegates (C#) (Varianz in Delegaten (C#)).

Titel Beschreibung
Varianz in generischen Schnittstellen Erläutert Ko- und Kontravarianz in generischen Schnittstellen und enthält eine Liste der Varianten generischen Schnittstellen in .NET Framework.
Creating Variant Generic Interfaces (C#) (Erstellen von varianten generischen Schnittstellen (C#)) Zeigt, wie benutzerdefinierte variante Schnittstellen erstellt werden.
Using Variance in Interfaces for Generic Collections (C#) (Verwenden von Varianz in Schnittstellen für generische Auflistungen (C#)) Zeigt, wie die Unterstützung durch Kovarianz und Kontravarianz bei IEnumerable<T>- und IComparable<T>-Schnittstellen bei der Wiederverwendung Ihres Codes helfen kann.
Variance in Delegates (C#) (Varianz bei Delegaten (C#)) Erläutert Ko- und Kontravarianz in generischen und nicht generischen Delegaten und stellt eine Liste von varianten generischen Delegaten im .NET Framework bereit.
Using Variance in Delegates (C#) (Verwenden von Varianz in Delegaten (C#)) Zeigt, wie die Unterstützung durch Kovarianz und Kontravarianz in nicht generischen Delegaten verwendet werden kann, um Methodensignaturen mit Delegattypen abzugleichen.
Verwenden von Varianz für die generischen Delegaten Func und Action (C#) Zeigt, wie die Unterstützung durch Kovarianz und Kontravarianz bei Func- und Action-Delegaten bei der Wiederverwendung Ihres Codes helfen kann.