Freigeben über


Varianz in generischen Schnittstellen (Visual Basic)

.NET Framework 4 hat die Varianzunterstützung für mehrere vorhandene generische Schnittstellen eingeführt. Die Varianzunterstützung ermöglicht die implizite Konvertierung von Klassen, die diese Schnittstellen implementieren. Die folgenden Schnittstellen sind jetzt variabel:

Bei der Kovarianz kann eine Methode einen abgeleiteteren Rückgabetyp haben als den, der durch den generischen Typparameter der Schnittstelle definiert wurde. Um das Kovarianzfeature zu veranschaulichen, betrachten Sie die folgenden allgemeinen Schnittstellen: IEnumerable(Of Object) und IEnumerable(Of String). Die IEnumerable(Of String) Schnittstelle erbt die IEnumerable(Of Object) Schnittstelle nicht. Der String Typ erbt jedoch den Object Typ, und in einigen Fällen können Sie Objekte dieser Schnittstellen einander zuweisen. Dies wird im folgenden Codebeispiel demonstriert.

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 Kompilierungsfehler in Visual Basic mit Option Strict On. Jetzt können Sie jedoch anstelle von strings, wie im vorherigen Beispiel gezeigt, verwendenobjects, da die IEnumerable<T> Schnittstelle kovariant ist.

Contravariance ermöglicht es einer Methode, Argumenttypen zu haben, die weniger abgeleitet sind als die durch den generischen Parameter der Schnittstelle angegebenen. Um die Kontravarianz zu veranschaulichen, gehen Sie davon aus, dass Sie eine BaseComparer Klasse erstellt haben, um Instanzen der BaseClass Klasse zu vergleichen. Der BaseComparer-Klasse implementiert die IEqualityComparer(Of BaseClass)-Schnittstelle. Da die IEqualityComparer<T>-Schnittstelle jetzt kontravariant ist, können Sie BaseComparer verwenden, um Instanzen von Klassen zu vergleichen, die die BaseClass-Klasse erben. Dies wird im folgenden Codebeispiel demonstriert.

' 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 der Varianz in Schnittstellen für generische Auflistungen (Visual Basic).

Die Varianz in generischen Schnittstellen wird nur für Referenztypen unterstützt. Werttypen unterstützen keine Varianz. Beispielsweise kann IEnumerable(Of Integer) nicht implizit in IEnumerable(Of Object) umgewandelt werden, da ganze Zahlen durch einen Werttyp 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 Variantenschnittstellen implementieren, immer noch invariant sind. Obwohl List<T> die kovariante Schnittstelle IEnumerable<T> implementiert, können Sie List(Of Object) nicht 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