Dela via


Varians i allmänna gränssnitt (Visual Basic)

.NET Framework 4 introducerade variansstöd för flera befintliga generiska gränssnitt. Avvikelsestöd möjliggör implicit konvertering av klasser som implementerar dessa gränssnitt. Följande gränssnitt är nu variant:

Med kovarians kan en metod ha en mer härledd returtyp än den som definieras av den generiska typparametern i gränssnittet. För att illustrera covariance-funktionen bör du överväga dessa allmänna gränssnitt: IEnumerable(Of Object) och IEnumerable(Of String). Gränssnittet IEnumerable(Of String) ärver IEnumerable(Of Object) inte gränssnittet. Men typen String ärver Object typen, och i vissa fall kanske du vill tilldela objekt av dessa gränssnitt till varandra. Detta visas i följande kodexempel.

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

I tidigare versioner av .NET Framework orsakar den här koden ett kompileringsfel i Visual Basic med Option Strict On. Men nu kan du använda strings i stället för objects, som du ser i föregående exempel, eftersom IEnumerable<T> gränssnittet är covariant.

Contravariance tillåter att en metod har argumenttyper som är mindre härledda än den som anges av den generiska parametern i gränssnittet. Anta att du har skapat en BaseComparer klass för att jämföra instanser av BaseClass klassen för att illustrera kontravarians. Klassen BaseComparer implementerar gränssnittet IEqualityComparer(Of BaseClass). IEqualityComparer<T> Eftersom gränssnittet nu är kontravariant kan du använda BaseComparer för att jämföra instanser av klasser som ärver BaseClass klassen. Detta visas i följande kodexempel.

' 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

Fler exempel finns i Använda varians i gränssnitt för generiska samlingar (Visual Basic).

Varians i allmänna gränssnitt stöds endast för referenstyper. Värdetyper stöder inte varians. Det IEnumerable(Of Integer) går till exempel inte att implicit konvertera till IEnumerable(Of Object), eftersom heltal representeras av en värdetyp.

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

Det är också viktigt att komma ihåg att klasser som implementerar variantgränssnitt fortfarande är invarianta. Även om List<T> du till exempel implementerar det covarianta gränssnittet IEnumerable<T>kan du inte implicit konvertera List(Of Object) till List(Of String). Detta illustreras i följande kodexempel.

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

Se även