In(泛型修饰符)(Visual Basic)

对于泛型类型参数,In 关键字可指定类型参数是逆变的。

注解

逆变使你使用的类型可以比泛型参数指定的类型派生程度更小。 这样可以隐式转换实现变体接口的类以及隐式转换委托类型。

有关详细信息,请参阅协变和逆变

规则

可以在泛型接口和委托中使用 In 关键字。

如果类型参数仅用作方法参数的类型,而不用作方法返回类型,则类型参数可以在泛型接口或委托中声明为逆变。 ByRef 参数不能为协变或逆变。

引用类型支持协变和逆变,但值类型不支持它们。

在 Visual Basic 中,如果不指定委托类型,则无法在逆变接口中声明事件。 此外,逆变接口不能有嵌套的类、枚举或结构,但可以有嵌套接口。

行为

具有逆变类型参数的接口使其方法接受的参数的类型可以比接口类型参数指定的类型派生程度更小。 例如,因为在 .NET Framework 4 的 IComparer<T> 接口中,类型 T 是逆变的,所以可以将 IComparer(Of Person) 类型的对象分配给 IComparer(Of Employee) 类型的对象,而无需使用任何特殊转换方法(如果 Employee 继承自 Person)。

可以向逆变委托分配相同类型的其他委托,不过要使用派生程度更小的泛型类型参数。

示例 - 逆变泛型接口

下面的示例演示如何声明、扩展和实现逆变泛型接口。 它还演示如何对实现此接口的类使用隐式转换。

' 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

请参阅