Variancia általános felületeken (Visual Basic)
.NET-keretrendszer 4 számos meglévő általános adapter varianciáját támogatja. A variancia-támogatás lehetővé teszi az ezen interfészeket megvalósító osztályok implicit átalakítását. A következő interfészek mostantól variálnak:
IEnumerable<T> (T kovariant)
IEnumerator<T> (T kovariant)
IQueryable<T> (T kovariant)
IGrouping<TKey,TElement> (
TKey
ésTElement
kovariant)IComparer<T> (T is contravariant)
IEqualityComparer<T> (T is contravariant)
IComparable<T> (T is contravariant)
A kovariancia lehetővé teszi, hogy egy metódus származtatottabb visszatérési típussal rendelkezzen, mint amelyet az interfész általános típusparamétere határoz meg. A kovariancia funkció szemléltetéséhez vegye figyelembe az alábbi általános felületeket: IEnumerable(Of Object)
és IEnumerable(Of String)
. A IEnumerable(Of String)
felület nem örökli a IEnumerable(Of Object)
felületet. A String
típus azonban örökli a Object
típust, és bizonyos esetekben érdemes lehet ezeknek a felületeknek az objektumait egymáshoz rendelni. Ez az alábbi példakódban látható.
Dim strings As IEnumerable(Of String) = New List(Of String)
Dim objects As IEnumerable(Of Object) = strings
A .NET-keretrendszer korábbi verzióiban ez a kód fordítási hibát okoz a Visual Basicben a következővelOption Strict On
: . Most azonban használhatja strings
objects
ahelyett, hogy az előző példában látható módon, mert a IEnumerable<T> felület kovariant.
A contravariance lehetővé teszi, hogy egy metódus olyan argumentumtípusokat használjon, amelyek kevésbé származnak, mint a felület általános paramétere által megadottak. A contravariance szemléltetéséhez tegyük fel, hogy létrehozott egy osztályt BaseComparer
az BaseClass
osztály példányainak összehasonlításához. Az BaseComparer
osztály megvalósítja az IEqualityComparer(Of BaseClass)
felületet. Mivel a IEqualityComparer<T> felület most már contravariant, az osztályt öröklő BaseClass
osztályok példányainak összehasonlítására használhatóBaseComparer
. Ez az alábbi példakódban látható.
' 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
További példákért lásd : Variancia használata általános gyűjteményekhez (Visual Basic).
Az általános felületek varianciája csak referenciatípusok esetén támogatott. Az értéktípusok nem támogatják a varianciát. Nem konvertálható IEnumerable(Of Object)
például IEnumerable(Of Integer)
implicit módon, mert az egész számokat értéktípus jelöli.
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
Azt is fontos megjegyezni, hogy a variáns interfészeket megvalósító osztályok még mindig invariánsak. Például, bár List<T> implementálja a kovariant felületet IEnumerable<T>, nem konvertálható List(Of Object)
List(Of String)
implicit módon. Ezt az alábbi példakód szemlélteti.
' 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)