Varianz in generischen Schnittstellen (C#)Variance in Generic Interfaces (C#)

In .NET Framework 4 wurde die Varianzunterstützung für mehrere vorhandene generische Schnittstellen eingeführt..NET Framework 4 introduced variance support for several existing generic interfaces. Die Varianzunterstützung lässt eine implizite Konvertierung von Klassen zu, die diese Schnittstellen implementieren.Variance support enables implicit conversion of classes that implement these interfaces. Die folgenden Schnittstellen sind jetzt variant:The following interfaces are now variant:

Kovarianz ermöglicht einer Methode, stärker abgeleitete Rückgabetypen zu verwenden, als durch die generischen Typparameter der Schnittstelle definiert sind.Covariance permits a method to have a more derived return type than that defined by the generic type parameter of the interface. Betrachten Sie diese generischen Schnittstellen zur Veranschaulichung der Kovarianzfunktionen: IEnumerable<Object> und IEnumerable<String>.To illustrate the covariance feature, consider these generic interfaces: IEnumerable<Object> and IEnumerable<String>. Die Schnittstelle IEnumerable<Object> wird nicht von der Schnittstelle IEnumerable<String> geerbt.The IEnumerable<String> interface does not inherit the IEnumerable<Object> interface. Allerdings erbt der Typ String den Typ Object. In einigen Fällen können Sie vielleicht auch die Objekte dieser Schnittstellen einander zuweisen.However, the String type does inherit the Object type, and in some cases you may want to assign objects of these interfaces to each other. Dies wird im folgenden Codebeispiel gezeigt.This is shown in the following code example.

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

In früheren Versionen des .NET Frameworks verursacht dieser Code einen Kompilierfehler mit Option Strict On in C#.In earlier versions of the .NET Framework, this code causes a compilation error in C# with Option Strict On. Jetzt können Sie aber strings anstelle von objects verwenden, wie im vorherigen Beispiel gezeigt wurde, da die IEnumerable<T>-Schnittstelle kovariant ist.But now you can use strings instead of objects, as shown in the previous example, because the IEnumerable<T> interface is covariant.

Kontravarianz ermöglicht einer Methode, Argumenttypen zu verwenden, die weniger stark abgeleitet sind als durch die generischen Parameter der Schnittstelle angegeben.Contravariance permits a method to have argument types that are less derived than that specified by the generic parameter of the interface. Nehmen Sie zur Veranschaulichung der Kontravarianz an, dass Sie eine BaseComparer-Klasse zum Vergleich von Instanzen der BaseClass-Klasse erstellt haben.To illustrate contravariance, assume that you have created a BaseComparer class to compare instances of the BaseClass class. Die BaseComparer-Klasse implementiert die IEqualityComparer<BaseClass>-Schnittstelle.The BaseComparer class implements the IEqualityComparer<BaseClass> interface. Da die Schnittstelle IEqualityComparer<T> jetzt kontravariant ist, können Sie BaseComparer verwenden, um Instanzen von Klassen zu vergleichen, die die Klasse BaseClass erben.Because the IEqualityComparer<T> interface is now contravariant, you can use BaseComparer to compare instances of classes that inherit the BaseClass class. Dies wird im folgenden Codebeispiel gezeigt.This is shown in the following code example.

// Simple hierarchy of classes.  
class BaseClass { }  
class DerivedClass : BaseClass { }  

// Comparer class.  
class BaseComparer : IEqualityComparer<BaseClass>   
{  
    public int GetHashCode(BaseClass baseInstance)  
    {  
        return baseInstance.GetHashCode();  
    }  
    public bool Equals(BaseClass x, BaseClass y)  
    {  
        return x == y;  
    }  
}  
class Program  
{  
    static void Test()  
    {  
        IEqualityComparer<BaseClass> baseComparer = new BaseComparer();  

        // Implicit conversion of IEqualityComparer<BaseClass> to   
        // IEqualityComparer<DerivedClass>.  
        IEqualityComparer<DerivedClass> childComparer = baseComparer;  
    }  
}  

Weitere Beispiele finden Sie unter Using Variance in Interfaces for Generic Collections (C#) (Verwenden von Varianz in Schnittstellen für generische Auflistungen (C#)).For more examples, see Using Variance in Interfaces for Generic Collections (C#).

Varianz in generischen Typparametern wird nur für Referenztypen unterstützt.Variance in generic interfaces is supported for reference types only. Werttypen unterstützen keine Varianz.Value types do not support variance. Beispielweise kann IEnumerable<int> nicht implizit in IEnumerable<object> konvertiert werden, da Ganzzahlen durch Werttypen dargestellt werden.For example, IEnumerable<int> cannot be implicitly converted to IEnumerable<object>, because integers are represented by a value type.

IEnumerable<int> integers = new List<int>();  
// The following statement generates a compiler errror,  
// because int is a value type.  
// IEnumerable<Object> objects = integers;  

Es ist auch wichtig zu beachten, dass Klassen, die variante Schnittstellen implementieren, trotzdem noch invariant sind.It is also important to remember that classes that implement variant interfaces are still invariant. Obwohl List<T> beispielsweise die kovariante Schnittstelle IEnumerable<T> implementiert, können Sie List<Object> implizit in List<String> konvertieren.For example, although List<T> implements the covariant interface IEnumerable<T>, you cannot implicitly convert List<Object> to List<String>. Dies wird im folgenden Codebeispiel veranschaulicht.This is illustrated in the following code example.

// The following line generates a compiler error  
// because classes are invariant.  
// List<Object> list = new List<String>();  

// You can use the interface object instead.  
IEnumerable<Object> listObjects = new List<String>();  

Siehe auchSee Also

Using Variance in Interfaces for Generic Collections (C#) (Verwenden von Varianz in Schnittstellen für generische Auflistungen (C#))Using Variance in Interfaces for Generic Collections (C#)
Creating Variant Generic Interfaces (C#) (Erstellen von varianten generischen Schnittstellen (C#))Creating Variant Generic Interfaces (C#)
Generische SchnittstellenGeneric Interfaces
Variance in Delegates (C#) (Varianz bei Delegaten (C#))Variance in Delegates (C#)