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.
Una interfaz covariante permite que sus métodos devuelvan más tipos derivados que los especificados en la interfaz. Una interfaz contravariante permite que sus métodos acepten parámetros de tipos menos derivados que los especificados en la interfaz.
En .NET Framework 4, varias interfaces existentes se convirtieron en covariante y contravariante. Estos incluyen IEnumerable<T> y IComparable<T>. Esto le permite reutilizar métodos que funcionan con colecciones genéricas de tipos base para colecciones de tipos derivados.
Para obtener una lista de interfaces variantes en .NET Framework, vea Varianza en interfaces genéricas (Visual Basic).
Conversión de colecciones genéricas
En el ejemplo siguiente se muestran las ventajas de la compatibilidad con la covarianza en la IEnumerable<T> interfaz. El PrintFullName método acepta una colección del IEnumerable(Of Person) tipo como parámetro. Sin embargo, puede volver a usarlo para una colección tipo IEnumerable(Of Person) porque Employee hereda Person.
' Simple hierarchy of classes.
Public Class Person
Public Property FirstName As String
Public Property LastName As String
End Class
Public Class Employee
Inherits Person
End Class
' The method has a parameter of the IEnumerable(Of Person) type.
Public Sub PrintFullName(ByVal persons As IEnumerable(Of Person))
For Each person As Person In persons
Console.WriteLine(
"Name: " & person.FirstName & " " & person.LastName)
Next
End Sub
Sub Main()
Dim employees As IEnumerable(Of Employee) = New List(Of Employee)
' You can pass IEnumerable(Of Employee),
' although the method expects IEnumerable(Of Person).
PrintFullName(employees)
End Sub
Comparación de colecciones genéricas
En el ejemplo siguiente se muestran las ventajas de la compatibilidad con la contravarianza en la interfaz IComparer<T>. La clase PersonComparer implementa la interfaz IComparer(Of Person). Sin embargo, puede reutilizar esta clase para comparar una secuencia de objetos del Employee tipo porque Employee hereda Person.
' Simple hierarchy of classes.
Public Class Person
Public Property FirstName As String
Public Property LastName As String
End Class
Public Class Employee
Inherits Person
End Class
' The custom comparer for the Person type
' with standard implementations of Equals()
' and GetHashCode() methods.
Class PersonComparer
Implements IEqualityComparer(Of Person)
Public Function Equals1(
ByVal x As Person,
ByVal y As Person) As Boolean _
Implements IEqualityComparer(Of Person).Equals
If x Is y Then Return True
If x Is Nothing OrElse y Is Nothing Then Return False
Return (x.FirstName = y.FirstName) AndAlso
(x.LastName = y.LastName)
End Function
Public Function GetHashCode1(
ByVal person As Person) As Integer _
Implements IEqualityComparer(Of Person).GetHashCode
If person Is Nothing Then Return 0
Dim hashFirstName =
If(person.FirstName Is Nothing,
0, person.FirstName.GetHashCode())
Dim hashLastName = person.LastName.GetHashCode()
Return hashFirstName Xor hashLastName
End Function
End Class
Sub Main()
Dim employees = New List(Of Employee) From {
New Employee With {.FirstName = "Michael", .LastName = "Alexander"},
New Employee With {.FirstName = "Jeff", .LastName = "Price"}
}
' You can pass PersonComparer,
' which implements IEqualityComparer(Of Person),
' although the method expects IEqualityComparer(Of Employee)
Dim noduplicates As IEnumerable(Of Employee) = employees.Distinct(New PersonComparer())
For Each employee In noduplicates
Console.WriteLine(employee.FirstName & " " & employee.LastName)
Next
End Sub