对于泛型类型参数, In
关键字指定类型参数是逆变的。
注解
使用逆变,可以使用的派生类型比泛型参数指定的类型少。 这允许隐式转换实现变体接口的类和委托类型的隐式转换。
有关详细信息,请参阅 协变和逆变。
规则
可以在泛型接口和委托中使用 In
关键字。
如果类型参数仅用作方法参数类型,而不用作方法返回类型,则可以在泛型接口或委托中声明类型。
ByRef
参数不能协变或逆变。
引用类型支持协变和逆变,值类型不支持协变。
在 Visual Basic 中,如果不指定委托类型,则不能在逆变接口中声明事件。 此外,逆变接口不能有嵌套类、枚举或结构,但它们可以有嵌套接口。
行为
具有逆变类型参数的接口允许其方法接受派生类型的自变量比接口类型参数指定的参数少。 例如,由于在 .NET Framework 4 中,在接口中IComparer<T>,类型 T 是逆变的IComparer(Of Employee)
,因此可以在继承自Person
时使用任何特殊转换方法Employee
的情况下,将该类型的对象IComparer(Of 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