【vs.net 2008系列】 9.宽松委托转换

通过进行 Visual Basic 2008 中引入的宽松委托转换,可以将 Sub 和函数分配给委托或处理程序,即使在签名不同时仍可如此。因此,委托绑定将与方法调用中已允许的绑定保持一致。

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

  • 必须存在从每个委托参数的数据类型到所分配函数或 Sub 的相应参数数据类型的扩大转换。在下面的代码中,委托 Del1 具一个参数 Integer。所分配的 lambda 表达式中的参数 m 必须具有一个数据类型(对于该数据类型,存在一个以 Integer 为转换来源的扩大转换),如 LongDouble

    Visual Basic
    ' Definition of delegate Del1.
                    Delegate Function Del1(ByVal arg As Integer) As Integer
                    
    Visual Basic
    ' 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 时,才允许进行收缩转换。

    Visual Basic
    ' 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

    Visual Basic
    ' 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,则会在两个方向上移除扩大限制。

Visual Basic
' 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)
            

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

Visual Basic
' Definition of delegate Del2, which has two parameters.
            Delegate Function Del2(ByVal arg1 As Integer, ByVal arg2 As String) As Integer
            
Visual Basic
' 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))
            

请注意,不能指定一些参数而忽略其他参数。

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

忽略参数功能在涉及一些复杂参数的情况下(如定义事件处理程序)非常有用。未使用某些事件处理程序的参数。但处理程序可以直接访问注册事件的控件的状态,并忽略这些参数。在不产生多义性时,宽松委托允许忽略此类声明中的参数。在下面的示例中,可以将完全指定的方法 OnClick 重新编写为 RelaxedOnClick

Visual Basic
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
            

在先前的示例中使用了 lambda 表达式,以便轻松地查看类型关系。但是,对于使用 AddressOfHandlesAddHandler 的委托分配,允许相同的宽松转换。

在下面的示例中,函数 f1f2f3f4 都可以分配给 Del1

Visual Basic
' Definition of delegate Del1.
            Delegate Function Del1(ByVal arg As Integer) As Integer
            
Visual Basic
' 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
            
Visual Basic
' 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 时,下面的示例才是有效的。

Visual Basic
' 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

Visual Basic
' 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
            
Visual Basic
' 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))
            
本文出处MSDN http://msdn.microsoft.com/zh-cn/library/bb531336.aspx

posted on 2008-10-21 16:05  黄昌楠  阅读(245)  评论(0)    收藏  举报

导航