Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O .NET Framework 4 introduziu suporte de variação para várias interfaces genéricas existentes. O suporte à variação permite a conversão implícita de classes que implementam essas interfaces. As seguintes interfaces agora são 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 essas 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, talvez você queira 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, conforme mostrado no exemplo anterior, porque a IEnumerable<T> interface é covariante.
A contravariância permite que um método tenha tipos de argumento menos derivados do que o especificado pelo parâmetro genérico da interface. Para ilustrar a contravariância, suponha que você tenha criado 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 Como usar variação em interfaces para coleções genéricas (Visual Basic).
A variação em interfaces genéricas tem suporte somente para tipos de referência. Os tipos de valor não dão suporte à variação. Por exemplo, IEnumerable(Of Integer) não pode ser convertido IEnumerable(Of Object)implicitamente em , porque os 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 invariáveis. 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)