In (универсальный модификатор) (Visual Basic)
Для параметров универсального типа ключевое слово In
указывает, что параметр типа является контравариантным.
Замечания
Контравариантность позволяет использовать производные типы со степенью наследования меньше, чем у типа, заданного универсальным параметром. Благодаря этому можно осуществлять неявное преобразование классов, реализующих вариантные интерфейсы, и неявное преобразование типов делегатов.
Дополнительные сведения см. в разделе Ковариация и контравариантность.
Правила
Ключевое слово In
может применяться в универсальных интерфейсах и делегатах.
Параметр типа может быть объявлен контравариантным в универсальном интерфейсе или делегате, если он используется только в качестве типа аргументов метода и не используется в качестве возвращаемого типа метода. ByRef
параметры не могут быть ковариантными или контравариантными.
Ковариация и контравариантность поддерживаются для ссылочных типов и не поддерживаются для типов значений.
В Visual Basic нельзя объявлять события в контравариантных интерфейсах без указания типа делегата. Кроме того, контравариантные интерфейсы не могут содержать вложенные классы, перечисления или структуры, но могут иметь вложенные интерфейсы.
Поведение
Интерфейс с параметром контравариантного типа позволяет своим методам принимать аргументы производных типов, степень наследования у которых меньше, чем у параметра типа интерфейса. Например, так как в платформа .NET Framework 4 в интерфейсе IComparer<T> тип T является контравариантным, можно назначить объект IComparer(Of Person)
типа объекту IComparer(Of Employee)
типа без использования специальных методов преобразования, если Employee
наследуется от Person
.
Контравариантный делегат может быть назначен другому делегату того же типа, но с производным параметром универсального типа меньшей степени.
Пример — универсальный интерфейс contravariant
В следующем примере показано, как объявить, расширить и реализовать контравариантный универсальный интерфейс. В нем также показано, как можно использовать неявное преобразование для классов, реализующих этот интерфейс.
' Contravariant interface.
Interface IContravariant(Of In A)
End Interface
' Extending contravariant interface.
Interface IExtContravariant(Of In A)
Inherits IContravariant(Of A)
End Interface
' Implementing contravariant interface.
Class Sample(Of A)
Implements IContravariant(Of A)
End Class
Sub Main()
Dim iobj As IContravariant(Of Object) = New Sample(Of Object)()
Dim istr As IContravariant(Of String) = New Sample(Of String)()
' You can assign iobj to istr, because
' the IContravariant interface is contravariant.
istr = iobj
End Sub
Пример — универсальный делегат contravariant
В следующем примере кода показано, как объявить контравариантный универсальный делегат. В нем также показано, как можно выполнить неявное преобразование типа делегата.
' Contravariant delegate.
Public Delegate Sub DContravariant(Of In A)(ByVal argument As A)
' Methods that match the delegate signature.
Public Shared Sub SampleControl(ByVal control As Control)
End Sub
Public Shared Sub SampleButton(ByVal control As Button)
End Sub
Private Sub Test()
' Instantiating the delegates with the methods.
Dim dControl As DContravariant(Of Control) =
AddressOf SampleControl
Dim dButton As DContravariant(Of Button) =
AddressOf SampleButton
' You can assign dControl to dButton
' because the DContravariant delegate is contravariant.
dButton = dControl
' Invoke the delegate.
dButton(New Button())
End Sub