Variance in Generic Interfaces (Visual Basic) (Varianz in generischen Schnittstellen (Visual Basic))

In .NET Framework 4 wurde die Varianzunterstützung für mehrere vorhandene generische Schnittstellen eingeführt. Die Varianzunterstützung lässt eine implizite Konvertierung von Klassen zu, die diese Schnittstellen implementieren. Die folgenden Schnittstellen sind jetzt variant:

Kovarianz ermöglicht einer Methode, stärker abgeleitete Rückgabetypen zu verwenden, als durch die generischen Typparameter der Schnittstelle definiert sind. Betrachten Sie diese generischen Schnittstellen zur Veranschaulichung der Kovarianzfunktionen: IEnumerable(Of Object) und IEnumerable(Of String). Die Schnittstelle IEnumerable(Of Object) wird nicht von der Schnittstelle IEnumerable(Of String) geerbt. Allerdings erbt der Typ String den Typ Object. In einigen Fällen können Sie vielleicht auch die Objekte dieser Schnittstellen einander zuweisen. Dies wird im folgenden Codebeispiel gezeigt.

Dim strings As IEnumerable(Of String) = New List(Of String)
Dim objects As IEnumerable(Of Object) = strings

In früheren Versionen von .NET Framework verursacht dieser Code einen Kompilierfehler mit Option Strict On in Visual Basic. Jetzt können Sie aber strings anstelle von objects verwenden, wie im vorherigen Beispiel gezeigt wurde, da die IEnumerable<T>-Schnittstelle kovariant ist.

Kontravarianz ermöglicht einer Methode, Argumenttypen zu verwenden, die weniger stark abgeleitet sind als durch die generischen Parameter der Schnittstelle angegeben. Nehmen Sie zur Veranschaulichung der Kontravarianz an, dass Sie eine BaseComparer-Klasse zum Vergleich von Instanzen der BaseClass-Klasse erstellt haben. Die BaseComparer-Klasse implementiert die IEqualityComparer(Of BaseClass)-Schnittstelle. Da die Schnittstelle IEqualityComparer<T> jetzt kontravariant ist, können Sie BaseComparer verwenden, um Instanzen von Klassen zu vergleichen, die die Klasse BaseClass erben. Dies wird im folgenden Codebeispiel gezeigt.

' Simple hierarchy of classes.
Class BaseClass
End Class

Class DerivedClass
    Inherits BaseClass
End Class

' Comparer class.
Class BaseComparer
    Implements IEqualityComparer(Of BaseClass)

    Public Function Equals1(ByVal x As BaseClass,
                            ByVal y As BaseClass) As Boolean _
                            Implements IEqualityComparer(Of BaseClass).Equals
        Return (x.Equals(y))
    End Function

    Public Function GetHashCode1(ByVal obj As BaseClass) As Integer _
        Implements IEqualityComparer(Of BaseClass).GetHashCode
        Return obj.GetHashCode
    End Function
End Class
Sub Test()
    Dim baseComparer As IEqualityComparer(Of BaseClass) = New BaseComparer
    ' Implicit conversion of IEqualityComparer(Of BaseClass) to
    ' IEqualityComparer(Of DerivedClass).
    Dim childComparer As IEqualityComparer(Of DerivedClass) = baseComparer
End Sub

Weitere Beispiele finden Sie unter Verwenden von Varianz in Schnittstellen für generische Sammlungen (Visual Basic).

Varianz in generischen Typparametern wird nur für Referenztypen unterstützt. Werttypen unterstützen keine Varianz. Beispielweise kann IEnumerable(Of Integer) nicht implizit in IEnumerable(Of Object) konvertiert werden, da Ganzzahlen durch Werttypen dargestellt werden.

Dim integers As IEnumerable(Of Integer) = New List(Of Integer)
' The following statement generates a compiler error
' with Option Strict On, because Integer is a value type.
' Dim objects As IEnumerable(Of Object) = integers

Es ist auch wichtig zu beachten, dass Klassen, die variante Schnittstellen implementieren, trotzdem noch invariant sind. Obwohl List<T> beispielsweise die kovariante Schnittstelle IEnumerable<T> implementiert, können Sie List(Of Object) implizit in List(Of String) konvertieren. Dies wird im folgenden Codebeispiel veranschaulicht.

' The following statement generates a compiler error
' because classes are invariant.
' Dim list As List(Of Object) = New List(Of String)

' You can use the interface object instead.
Dim listObjects As IEnumerable(Of Object) = New List(Of String)

Siehe auch