在 Visual Basic 中,协变和逆变这两种机制为数组类型、委托类型以及泛型类型参数启用隐式引用转换。 协变会保留赋值兼容性,而逆变会反转赋值兼容性。
以下代码演示了分配兼容性、协变和逆变之间的差异。
' Assignment compatibility.
Dim str As String = "test"
' An object of a more derived type is assigned to an object of a less derived type.
Dim obj As Object = str
' Covariance.
Dim strings As IEnumerable(Of String) = New List(Of String)()
' An object that is instantiated with a more derived type argument
' is assigned to an object instantiated with a less derived type argument.
' Assignment compatibility is preserved.
Dim objects As IEnumerable(Of Object) = strings
' Contravariance.
' Assume that there is the following method in the class:
' Shared Sub SetObject(ByVal o As Object)
' End Sub
Dim actObject As Action(Of Object) = AddressOf SetObject
' An object that is instantiated with a less derived type argument
' is assigned to an object instantiated with a more derived type argument.
' Assignment compatibility is reversed.
Dim actString As Action(Of String) = actObject
数组的协变使派生程度更大的类型的数组能够隐式转换为派生程度更小的类型的数组。 但此操作不类型安全,如以下代码示例所示。
Dim array() As Object = New String(10) {}
' The following statement produces a run-time exception.
' array(0) = 10
方法组的协变和逆变支持允许将方法签名与委托类型匹配。 通过这种匹配,不仅可以向委托分配具有匹配签名的方法,还可以分配以下内容的方法:
- 返回比委托类型指定的返回类型更派生的类型(协变)。
- 接受派生类型(逆变)少于委托类型指定的参数。
有关详细信息,请参阅委托中的变体 (Visual Basic) 和使用委托中的变体 (Visual Basic)。
下面的代码示例显示了对方法组的协变和逆变支持。
Shared Function GetObject() As Object
Return Nothing
End Function
Shared Sub SetObject(ByVal obj As Object)
End Sub
Shared Function GetString() As String
Return ""
End Function
Shared Sub SetString(ByVal str As String)
End Sub
Shared Sub Test()
' Covariance. A delegate specifies a return type as object,
' but you can assign a method that returns a string.
Dim del As Func(Of Object) = AddressOf GetString
' Contravariance. A delegate specifies a parameter type as string,
' but you can assign a method that takes an object.
Dim del2 As Action(Of String) = AddressOf SetObject
End Sub
在 .NET Framework 4 或更高版本中,Visual Basic 支持泛型接口和委托中的协变和逆变,并允许隐式转换泛型类型参数。 有关更多信息,请参阅泛型接口中的方差(Visual Basic)和委托中的方差(Visual Basic)。
下面的代码示例演示泛型接口的隐式引用转换。
Dim strings As IEnumerable(Of String) = New List(Of String)
Dim objects As IEnumerable(Of Object) = strings
泛型接口或委托在其泛型参数声明为协变或逆变时,被称为变体。 使用 Visual Basic 可以创建自己的变体接口和委托。 有关详细信息,请参阅创建变体泛型接口(Visual Basic)和委托中的变体(Visual Basic)。
相关文章
标题 | DESCRIPTION |
---|---|
泛型接口中的方差 (Visual Basic) | 讨论泛型接口中的协变和逆变,并提供 .NET Framework 中变体泛型接口的列表。 |
创建变体泛型接口 (Visual Basic) | 演示如何创建自定义变体接口。 |
在泛型集合接口中运用变体 (Visual Basic) | 在IEnumerable<T>和IComparable<T>接口中显示协变和逆变支持如何帮助你重用代码。 |
委托中的变体 (Visual Basic) | 讨论泛型委托和非泛型委托中的协变和逆变,并在 .NET Framework 中提供变体泛型委托的列表。 |
使用委托中的变体 (Visual Basic) | 演示如何在非泛型委托中使用协变和逆变支持,将方法签名与委托类型匹配。 |
对 Func 和 Action 泛型委托使用变体 (Visual Basic) | 演示 Func 委托和 Action 委托中对协变和逆变的支持如何帮助重复使用代码。 |