Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
.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:
IEnumerable<T> (T är covariant)
IEnumerator<T> (T är covariant)
IQueryable<T> (T är covariant)
IGrouping<TKey,TElement> (
TKey
ochTElement
är covariant)IComparer<T> (T är kontravariant)
IEqualityComparer<T> (T är kontravariant)
IComparable<T> (T är kontravariant)
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 inte gränssnittet IEnumerable(Of Object)
. 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> implementerar det covarianta gränssnittet IEnumerable<T> kan du till exempel 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)