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

См. также