Partager via


Variance dans les interfaces génériques (Visual Basic)

.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 :

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)

Voir aussi