Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Ковариантный интерфейс позволяет своим методам возвращать более производные типы, чем указанные в интерфейсе. Контравариантный интерфейс позволяет своим методам принимать параметры менее производных типов, чем указанные в интерфейсе.
В .NET Framework 4 несколько существующих интерфейсов стали ковариантными и контравариантными. В их числе IEnumerable<T> и IComparable<T>. Это позволяет повторно использовать методы, работающие с универсальными коллекциями базовых типов для коллекций производных типов.
Список вариантов интерфейсов в .NET Framework см. в разделе "Вариативность" в универсальных интерфейсах (Visual Basic).
Преобразование универсальных коллекций
В следующем примере показаны преимущества поддержки ковариации в интерфейсе IEnumerable<T> . Метод PrintFullName принимает коллекцию IEnumerable(Of Person) типа в качестве параметра. Однако его можно повторно использовать для коллекции IEnumerable(Of Person) типа, так как Employee наследуется 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
Сравнение универсальных коллекций
В следующем примере показаны преимущества поддержки контравариантности в интерфейсе IComparer<T> . Класс PersonComparer реализует интерфейс IComparer(Of Person). Однако этот класс можно повторно использовать для сравнения последовательности объектов Employee типа, так как Employee наследуется 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