Delen via


Afwijking in algemene interfaces (Visual Basic)

.NET Framework 4 heeft variantieondersteuning geïntroduceerd voor verschillende bestaande algemene interfaces. Variantieondersteuning maakt impliciete conversie mogelijk van klassen die deze interfaces implementeren. De volgende interfaces zijn nu variant:

Met covariantie kan een methode een meer afgeleid retourtype hebben dan dat is gedefinieerd door de algemene typeparameter van de interface. Als u de covariantiefunctie wilt illustreren, kunt u de volgende algemene interfaces overwegen: IEnumerable(Of Object) en IEnumerable(Of String). De IEnumerable(Of String) interface neemt de IEnumerable(Of Object) interface niet over. Het String type neemt echter het Object type over en in sommige gevallen wilt u mogelijk objecten van deze interfaces aan elkaar toewijzen. Dit wordt weergegeven in het volgende codevoorbeeld.

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

In eerdere versies van .NET Framework veroorzaakt deze code een compilatiefout in Visual Basic met Option Strict On. Maar nu kunt u in plaats van objects, zoals wordt weergegeven in het vorige voorbeeld, omdat strings de IEnumerable<T> interface covariant is.

Met contravariantie kan een methode argumenttypen hebben die minder zijn afgeleid dan die zijn opgegeven door de algemene parameter van de interface. Als u de contravariantie wilt illustreren, gaat u ervan uit dat u een BaseComparer klasse hebt gemaakt om exemplaren van de BaseClass klasse te vergelijken. Met de klasse BaseComparer wordt de IEqualityComparer(Of BaseClass)-interface geïmplementeerd. Omdat de IEqualityComparer<T> interface nu contravariant is, kunt u exemplaren BaseComparer van klassen vergelijken die de BaseClass klasse overnemen. Dit wordt weergegeven in het volgende codevoorbeeld.

' 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

Zie Variantie gebruiken in interfaces voor algemene verzamelingen (Visual Basic) voor meer voorbeelden.

Variantie in algemene interfaces wordt alleen ondersteund voor referentietypen. Waardetypen bieden geen ondersteuning voor variantie. Kan bijvoorbeeld IEnumerable(Of Integer) niet impliciet worden geconverteerd naar IEnumerable(Of Object), omdat gehele getallen worden vertegenwoordigd door een waardetype.

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

Het is ook belangrijk te onthouden dat klassen die variantinterfaces implementeren, nog steeds invariant zijn. Hoewel de covariant-interface IEnumerable<T>bijvoorbeeld List<T> wordt geïmplementeerd, kunt u niet impliciet converteren List(Of Object) naar List(Of String). Dit wordt geïllustreerd in het volgende codevoorbeeld.

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

Zie ook