In (универсальный модификатор) (Visual Basic)
Для параметров универсального типа ключевое слово In указывает, что тип параметра является контравариантным.
Заметки
Контравариантность позволяет использовать производный тип меньшей глубины наследования, нежели у типа, заданного универсальным параметром. Благодаря этому можно осуществлять неявное преобразование классов, реализующих вариантные интерфейсы, и неявное преобразование типов делегатов.
Дополнительные сведения см. в разделе Ковариация и контравариация (C# и Visual Basic).
Правила
Ключевое слово In может применяться в универсальных интерфейсах и делегатах.
Параметр типа может быть объявлен контравариантным в универсальном интерфейсе или делегате, если он применяется только как тип аргументов метода и не используется как тип значений, возвращаемых методом. Параметры ByRef не могут быть ковариантными или контравариантными.
Ковариация и контравариация поддерживаются для ссылочных типов, но не для типов значений.
В Visual Basic нельзя объявить события в контравариантных интерфейсах без указания типа делегата. Кроме того, контравариантный интерфейс не может включать вложенные классы, перечисления или структуры, но может включать вложенные интерфейсы.
Поведение
Интерфейс с параметром контравариантного типа позволяет своим методам принимать аргументы производных типов, глубина наследования у которых меньше, чем у типов, заданных параметром типа интерфейса. Например, поскольку в интерфейсе IComparer<T> в .NET Framework 4 тип T является контравариантным, можно назначить объект типа IComparer(Of Person) объекту типа IComparer(Of Employee) без применения каких-либо специальных методов преобразования, если Person наследует от Employee.
Контравариантный делегат может быть назначен другому делегату того же типа, но с менее производным параметром универсального типа.
Пример
В следующем примере показано, как объявить, расширить и реализовать контравариантный универсальный интерфейс. В нем также показано, как используется неявное преобразование для классов, которые реализуют этот интерфейс.
' 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 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
См. также
Ссылки
Out (универсальный модификатор) (Visual Basic)
Основные понятия
Вариативность в универсальных интерфейсах (C# и Visual Basic)