宽松委托转换 (Visual Basic)

宽松委托转换使你能够将子和函数分配给委托或处理程序,即使它们的签名不相同。 因此,绑定到委托与方法调用已允许的绑定保持一致。

参数和返回类型

为了完全匹配签名,宽松转换要求在 设置为 时满足 Option Strict 以下条件 On

  • 必须存在从每个委托参数的数据类型到所分配函数或 的相应参数的数据类型的扩大转换 Sub 。 在下面的示例中,委托有 Del1 一个参数 ,即 Integer 。 所分配 lambda 表达式中的参数必须具有数据类型,该数据类型从 (如 m 或 )进行扩大 Integer Long 转换 Double

    ' Definition of delegate Del1.
    Delegate Function Del1(ByVal arg As Integer) As Integer
    
    ' Valid lambda expression assignments with Option Strict on or off:
    
    ' Integer matches Integer.
    Dim d1 As Del1 = Function(m As Integer) 3
    
    ' Integer widens to Long
    Dim d2 As Del1 = Function(m As Long) 3
    
    ' Integer widens to Double
    Dim d3 As Del1 = Function(m As Double) 3
    

    只有在 设置为 时,才允许 Option Strict 收缩转换 Off

    ' Valid only when Option Strict is off:
    
    Dim d4 As Del1 = Function(m As String) CInt(m)
    Dim d5 As Del1 = Function(m As Short) m
    
  • 扩大转换必须与所分配函数的返回类型或委托的返回类型相反 Sub 。 在下面的示例中,每个分配的 lambda 表达式的正文必须计算为扩大为 的数据类型,因为 Integer 的返回 del1 类型为 Integer

    ' Valid return types with Option Strict on:
    
    ' Integer matches Integer.
    Dim d6 As Del1 = Function(m As Integer) m
    
    ' Short widens to Integer.
    Dim d7 As Del1 = Function(m As Long) CShort(m)
    
    ' Byte widens to Integer.
    Dim d8 As Del1 = Function(m As Double) CByte(m)
    

如果 Option Strict 设置为 Off ,则两个方向均会删除扩大限制。

' Valid only when Option Strict is set to Off.

' Integer does not widen to Short in the parameter.
Dim d9 As Del1 = Function(n As Short) n

' Long does not widen to Integer in the return type.
Dim d10 As Del1 = Function(n As Integer) CLng(n)

省略参数规范

宽松委托还允许在分配的方法中完全省略参数规范:

' Definition of delegate Del2, which has two parameters.
Delegate Function Del2(ByVal arg1 As Integer, ByVal arg2 As String) As Integer
' The assigned lambda expression specifies no parameters, even though
' Del2 has two parameters. Because the assigned function in this 
' example is a lambda expression, Option Strict can be on or off.
' Compare the declaration of d16, where a standard function is assigned.
Dim d11 As Del2 = Function() 3

' The parameters are still there, however, as defined in the delegate.
Console.WriteLine(d11(5, "five"))

' Not valid.
' Console.WriteLine(d11())
' Console.WriteLine(d11(5))

请注意,不能指定某些参数并省略其他参数。

' Not valid.
'Dim d12 As Del2 = Function(p As Integer) p

省略参数的能力对于定义事件处理程序(涉及多个复杂参数)非常有用。 不会使用某些事件处理程序的参数。 相反,处理程序直接访问注册事件的控件的状态,并忽略参数。 宽松委托允许你在无多义性结果时省略此类声明中的参数。 在下面的示例中,完全指定的方法 OnClick 可以重写为 RelaxedOnClick

Sub OnClick(ByVal sender As Object, ByVal e As EventArgs) Handles b.Click  
    MessageBox.Show("Hello World from" + b.Text)  
End Sub  
  
Sub RelaxedOnClick() Handles b.Click  
    MessageBox.Show("Hello World from" + b.Text)  
End Sub  

AddressOf 示例

前面示例中使用了 Lambda 表达式,使类型关系易于查看。 但是,对于使用 、 或 的委托分配,允许 AddressOf 相同的 Handles 放宽 AddHandler

在下面的示例中,函数 f1 、、 和 f2 f3 f4 都可以分配给 Del1

' Definition of delegate Del1.
Delegate Function Del1(ByVal arg As Integer) As Integer
' Definitions of f1, f2, f3, and f4.
Function f1(ByVal m As Integer) As Integer
End Function

Function f2(ByVal m As Long) As Integer
End Function

Function f3(ByVal m As Integer) As Short
End Function

Function f4() As Integer
End Function
' Assignments to function delegate Del1.

' Valid AddressOf assignments with Option Strict on or off:

' Integer parameters of delegate and function match.
Dim d13 As Del1 = AddressOf f1

' Integer delegate parameter widens to Long.
Dim d14 As Del1 = AddressOf f2

' Short return in f3 widens to Integer.
Dim d15 As Del1 = AddressOf f3

以下示例仅在 设置为 Option Strict 时有效 Off

' If Option Strict is Off, parameter specifications for f4 can be omitted.
Dim d16 As Del1 = AddressOf f4

' Function d16 still requires a single argument, however, as specified
' by Del1.
Console.WriteLine(d16(5))

' Not valid.
'Console.WriteLine(d16())
'Console.WriteLine(d16(5, 3))

删除函数返回

通过宽松委托转换,可以将函数分配给 Sub 委托,从而有效地忽略函数的返回值。 但是,不能将 Sub 分配给函数委托。 在下面的示例中,函数的地址 doubler 被分配给委托 Sub Del3

' Definition of Sub delegate Del3.
Delegate Sub Del3(ByVal arg1 As Integer)

' Definition of function doubler, which both displays and returns the
' value of its integer parameter.
Function doubler(ByVal p As Integer) As Integer
    Dim times2 = 2 * p
    Console.WriteLine("Value of p: " & p)
    Console.WriteLine("Double p:   " & times2)
    Return times2
End Function
' You can assign the function to the Sub delegate:
Dim d17 As Del3 = AddressOf doubler

' You can then call d17 like a regular Sub procedure.
d17(5)

' You cannot call d17 as a function. It is a Sub, and has no 
' return value.
' Not valid.
'Console.WriteLine(d17(5))

请参阅