Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
O .NET Framework 4 introduziu o suporte à variância para várias interfaces genéricas existentes. O suporte à variância permite a conversão implícita de classes que implementam essas interfaces. As seguintes interfaces são agora variantes:
IEnumerable<T> (T é covariante)
IEnumerator<T> (T é covariante)
IQueryable<T> (T é covariante)
IGrouping<TKey,TElement> (
TKeyeTElementsão covariantes)IComparer<T> (T é contravariante)
IEqualityComparer<T> (T é contravariante)
IComparable<T> (T é contravariante)
A covariância permite que um método tenha um tipo de retorno mais derivado do que o definido pelo parâmetro de tipo genérico da interface. Para ilustrar o recurso de covariância, considere estas interfaces genéricas: IEnumerable(Of Object) e IEnumerable(Of String). A IEnumerable(Of String) interface não herda a IEnumerable(Of Object) interface. No entanto, o String tipo herda o Object tipo e, em alguns casos, você pode querer atribuir objetos dessas interfaces uns aos outros. Isso é mostrado no exemplo de código a seguir.
Dim strings As IEnumerable(Of String) = New List(Of String)
Dim objects As IEnumerable(Of Object) = strings
Em versões anteriores do .NET Framework, esse código causa um erro de compilação no Visual Basic com Option Strict On. Mas agora você pode usar strings em vez de objects, como mostrado no exemplo anterior, porque a IEnumerable<T> interface é covariante.
A contravariância permite que um método tenha tipos de argumento que são menos derivados do que o especificado pelo parâmetro genérico da interface. Para ilustrar a contravariância, suponha que você criou uma BaseComparer classe para comparar instâncias da BaseClass classe. A classe BaseComparer implementa a interface IEqualityComparer(Of BaseClass). Como a IEqualityComparer<T> interface agora é contravariante, você pode usar BaseComparer para comparar instâncias de classes que herdam a BaseClass classe. Isso é mostrado no exemplo de código a seguir.
' 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 obter mais exemplos, consulte Usando variância em interfaces para coleções genéricas (Visual Basic).
A variância em interfaces genéricas é suportada apenas para tipos de referência. Os tipos de valor não suportam variância. Por exemplo, IEnumerable(Of Integer) não pode ser convertido implicitamente em IEnumerable(Of Object), porque inteiros são representados por um 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
Também é importante lembrar que as classes que implementam interfaces variantes ainda são invariantes. Por exemplo, embora List<T> implemente a interface IEnumerable<T>covariante, você não pode converter List(Of Object) implicitamente em List(Of String). Isso é ilustrado no exemplo de código a seguir.
' 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)