Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
.NET Framework 4 a introduit la prise en charge des variances pour plusieurs interfaces génériques existantes. La prise en charge de la variance permet la conversion implicite de classes qui implémentent ces interfaces. Les interfaces suivantes sont désormais des variantes :
IEnumerable<T> (T est covariant)
IEnumerator<T> (T est covariant)
IQueryable<T> (T est covariant)
IGrouping<TKey,TElement> (
TKey
etTElement
sont covariants)IComparer<T> (T est contravariant)
IEqualityComparer<T> (T est contravariant)
IComparable<T> (T est contravariant)
La covariance permet à une méthode d’avoir un type de retour plus dérivé que celui défini par le paramètre de type générique de l’interface. Pour illustrer la fonctionnalité de covariance, tenez compte des interfaces génériques suivantes : IEnumerable(Of Object)
et IEnumerable(Of String)
. L’interface IEnumerable(Of String)
n’hérite pas de l’interface IEnumerable(Of Object)
. Toutefois, le String
type hérite du Object
type et, dans certains cas, vous souhaiterez peut-être affecter des objets de ces interfaces les uns aux autres. Ceci est illustré dans l’exemple de code suivant.
Dim strings As IEnumerable(Of String) = New List(Of String)
Dim objects As IEnumerable(Of Object) = strings
Dans les versions antérieures du .NET Framework, ce code provoque une erreur de compilation dans Visual Basic avec Option Strict On
. Mais maintenant, vous pouvez utiliser strings
au lieu de objects
, comme indiqué dans l’exemple précédent, car l’interface IEnumerable<T> est covariante.
La contravariance permet à une méthode d’avoir des types d’arguments moins dérivés que ceux spécifiés par le paramètre générique de l’interface. Pour illustrer la contravariance, supposons que vous avez créé une BaseComparer
classe pour comparer les instances de la BaseClass
classe. La classe BaseComparer
implémente l’interface IEqualityComparer(Of BaseClass)
. Étant donné que l’interface IEqualityComparer<T> est désormais contravariante, vous pouvez utiliser BaseComparer
pour comparer des instances de classes qui héritent de la BaseClass
classe. Ceci est illustré dans l’exemple de code suivant.
' 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
Pour plus d’exemples, consultez Utilisation de la variance dans les interfaces pour les collections génériques (Visual Basic).
La variance dans les interfaces génériques est prise en charge uniquement pour les types de référence. Les types valeur ne prennent pas en charge la variance. Par exemple, IEnumerable(Of Integer)
ne peut pas être converti implicitement en IEnumerable(Of Object)
, car les entiers sont représentés par un type valeur.
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
Il est également important de se rappeler que les classes qui implémentent des interfaces variant sont toujours invariantes. Par exemple, bien qu’implémente List<T> l’interface IEnumerable<T>covariante, vous ne pouvez pas convertir List(Of Object)
implicitement en List(Of String)
. Ceci est illustré dans l’exemple de code suivant.
' 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)