Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
.NET Framework 4 introdujo compatibilidad de varianza para varias interfaces genéricas existentes. La compatibilidad con la varianza permite la conversión implícita de clases que implementan estas interfaces. Las interfaces siguientes ahora son variantes:
IEnumerable<T> (T es covariante)
IEnumerator<T> (T es covariante)
IQueryable<T> (T es covariante)
IGrouping<TKey,TElement> (
TKeyyTElementson covariantes)IComparer<T> (T es contravariante)
IEqualityComparer<T> (T es contravariante)
IComparable<T> (T es contravariante)
La Covarianza permite que un método tenga un tipo de valor devuelto más derivado que el definido por el parámetro de tipo genérico de la interfaz. Para ilustrar la característica de covarianza, tenga en cuenta estas interfaces genéricas: IEnumerable(Of Object) y IEnumerable(Of String). La IEnumerable(Of String) interfaz no hereda la IEnumerable(Of Object) interfaz. Sin embargo, el String tipo hereda el Object tipo y, en algunos casos, es posible que desee asignar objetos de estas interfaces entre sí. Esto se muestra en el ejemplo de código siguiente.
Dim strings As IEnumerable(Of String) = New List(Of String)
Dim objects As IEnumerable(Of Object) = strings
En versiones anteriores de .NET Framework, este código provoca un error de compilación en Visual Basic con Option Strict On. Pero ahora puede usar strings en lugar de objects, como se muestra en el ejemplo anterior, porque la IEnumerable<T> interfaz es covariante.
Contravariance permite que un método tenga tipos de argumentos menos derivados que los especificados por el parámetro genérico de la interfaz. Para ilustrar la contravarianza, supongamos que ha creado una BaseComparer clase para comparar instancias de la BaseClass clase. La clase BaseComparer implementa la interfaz IEqualityComparer(Of BaseClass). Dado que la IEqualityComparer<T> interfaz ahora es contravariante, puede usar BaseComparer para comparar instancias de clases que heredan la BaseClass clase. Esto se muestra en el ejemplo de código siguiente.
' 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
Para obtener más ejemplos, vea Usar varianza en interfaces para colecciones genéricas (Visual Basic).
La varianza para interfaces genéricas solo es compatible con tipos de referencia. Los tipos de valor no admiten la varianza. Por ejemplo, IEnumerable(Of Integer) no se puede convertir implícitamente en IEnumerable(Of Object), porque los enteros se representan mediante un tipo de valor.
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
También es importante recordar que las clases que implementan interfaces variant siguen siendo invariables. Por ejemplo, aunque List<T> implementa la interfaz IEnumerable<T>covariante , no se puede convertir List(Of Object) implícitamente a List(Of String). Esto se muestra en el ejemplo de código siguiente.
' 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)