Variantie gebruiken in interfaces voor algemene verzamelingen (Visual Basic)
Met een covariant-interface kunnen de methoden meer afgeleide typen retourneren dan de typen die zijn opgegeven in de interface. Met een contravariant-interface kunnen de methoden parameters van minder afgeleide typen accepteren dan de parameters die zijn opgegeven in de interface.
In .NET Framework 4 werden verschillende bestaande interfaces covariant en contravariant. Deze omvatten IEnumerable<T> en IComparable<T>. Hiermee kunt u methoden hergebruiken die werken met algemene verzamelingen basistypen voor verzamelingen van afgeleide typen.
Zie Variantie in Generic Interfaces (Visual Basic) voor een lijst met variantinterfaces in .NET Framework.
Algemene verzamelingen converteren
In het volgende voorbeeld ziet u de voordelen van covariantieondersteuning in de IEnumerable<T> interface. De PrintFullName
methode accepteert een verzameling van het IEnumerable(Of Person)
type als parameter. U kunt het echter opnieuw gebruiken voor een verzameling van het IEnumerable(Of Person)
type, omdat Employee
deze Person
wordt overgenomen.
' 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
Algemene verzamelingen vergelijken
In het volgende voorbeeld ziet u de voordelen van contravariantieondersteuning in de IComparer<T> interface. Met de klasse PersonComparer
wordt de IComparer(Of Person)
-interface geïmplementeerd. U kunt deze klasse echter opnieuw gebruiken om een reeks objecten van het Employee
type te vergelijken, omdat Employee
ze overnemen 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