宽松委托转换(Relaxed delegate conversion)在 Visual Basic 2008 中引入,允许您将子过程或函数赋值给委托或处理器(handlers),尽管它们的签名不一致。因而,绑定到委托变得与绑定方法调用(method invocation)一样。
参数和返回类型
用宽松转换取代精确签名匹配,当 Option Strict 选项要设置为 On 时,需要满足以下两条件:
    * 条件1 传参   
从委托的每个参数到赋值函数或子过程(assigned function or Sub)的相对应参数,必须存在扩大转换(widening conversion)。在下面的例子中,委托 Del1 有一个 Integer 类型的参数,赋值 lambda 表达式(assigned lambda expressions)的参数 m 的类型必须可以从 Integer 扩大转换,如 Long 或 Double。
      ' 定义委托 Del1.
      Delegate Function Del1(ByVal arg As Integer) As Integer

' Option Strict 为 on 或 off, 都是正确的 lambda 表达式赋值

' 整型匹配
      Dim d1 As Del1 = Function(m As Integer) 3

' Integer 扩大为 Long
      Dim d2 As Del1 = Function(m As Long) 3

' Integer 扩大为 Double
      Dim d3 As Del1 = Function(m As Double) 3

只有 Option Strict 设置为 Off 的时候,才允许缩小转换(Narrowing conversion。

' 仅当 Option Strict 为 off 才正确:

Dim d4 As Del1 = Function(m As String) CInt(m)
      Dim d5 As Del1 = Function(m As Short) m

    *条件2 返回值
跟参数相反,从赋值函数或子过程(assigned function or Sub)的返回值类型 到 委托的返回值类型 必须存在扩大转换。下面的例子中,因为委托 Del1的返回类型是 Integer,所以每个赋值 lambda 表达式(assigned lambda expression)必须(可以)扩大到 Integer。
      ' 当 Option Strict 为on 时是正确返回值:

' 整型匹配.
      Dim d6 As Del1 = Function(m As Integer) m

' Short 扩大为 Integer.
      Dim d7 As Del1 = Function(m As Long) CShort(m)

' Byte 扩大为 Integer.
      Dim d8 As Del1 = Function(m As Double) CByte(m)

如果 Option Strict 设置为 Off,传参和返回值没有扩大转换的限制。
' 仅当 Option Strict 设为 Off 时才正确.

' Integer 型参数没有扩展为 Short 
Dim d9 As Del1 = Function(n As Short) n

' 返回值 Long 型没有扩展为 Integer 
Dim d10 As Del1 = Function(n As Integer) CLng(n)

忽略参数规格
宽松委托(Relaxed delegate)允许您完全忽略赋值方法(assigned method)的参数规格
' 定义委托 Del2, 带两个参数
Delegate Function Del2(ByVal arg1 As Integer, ByVal arg2 As String) As Integer

' 赋值 lambda 表达式没有参数,尽管 Del2 有两个参数。因为在本例子中赋值函数(assigned function)
' 是 lambda 表达式,Option Strict 可以是 On 或者 Off。比较 d16 的声明,赋予了标准的方法。
Dim d11 As Del2 = Function() 3

' 参数仍然要传值,不过类型在委托中定义
Console.WriteLine(d11(5, "five"))

' 错误
' Console.WriteLine(d11())
' Console.WriteLine(d11(5))

注意,您不能只列某些参数,而忽略其它参数。
' 错误
'Dim d12 As Del2 = Function(p As Integer) p
忽略参数的特性很有用,特别是在事件处理器(event handler)方面,有很多复杂参数时,而某些参数不使用。这样,处理器直接访问事件所注册控件的状态,并且忽略参数。当不存在歧义时,宽松委托允许您忽略参数。下面的例子,标准的 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 作委托赋值(delegate assignment),类型关系就不那么明显了。

下面的例子,函数 f1, f2, f3, 和 f4 可以赋值给 Del1。

' 声明函数委托 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

' 给函数委托 Del1 赋值

' 正确的 AddressOf 赋值,Option Strict 可为 on 或 off:

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

' 整型委托参数扩大为 Long.
Dim d14 As Del1 = AddressOf f2

' f3 的 Short 返回类型扩大为 Integer.
Dim d15 As Del1 = AddressOf f3

以下例子仅当 Option Strict 为 Off 是才正确。

' 如果 Option Strict 设置 Off,f4 的参数规范可以省略
Dim d16 As Del1 = AddressOf f4

' 函数 d16 仍然需要一个参数,在 Del1 定义的
Console.WriteLine(d16(5))

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

丢弃函数返回值
宽松委托转换(Relaxed delegate conversion)允许您将一个函数(Function)赋值给子过程委托(Sub delegate),忽略掉函数的返回值。但是您不能够将子过程(Sub)赋值给函数委托(Function Delegate)。下面的例子,函数 doubler 的地址复制给 Sub 委托 Del3。
' 定义 Sub 委托 Del3.
Delegate Sub Del3(ByVal arg1 As Integer)

' 定义函数 doubler, 显示并返回整型参数的值
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

' 您可以把函数赋值给 Sub 委托:
Dim d17 As Del3 = AddressOf doubler

' 您可以向普通 Sub 过程一样调用 d17
d17(5)

' 您不可以将 d17 作为函数调用,它是一个 Sub 过程,没有返回值。
' 错误
'Console.WriteLine(d17(5))

转载于:https://www.cnblogs.com/feixian49/archive/2010/05/18/1738647.html

宽松委托转换(Relaxed delegate conversion)相关推荐

  1. C#编程利器之四:委托与事件(Delegate and event) (上)

    本文试图在.net Framework环境下,使用C#语言来描述委托.事件的概貌.希望本文能有助于大家理解委托.事件的概念,理解委托.事件的用途,理解它的C#实现方法,理解委托与事件为我们带来的好处. ...

  2. C++用户自定义转换(User-Defined Conversion)

    C++用户自定义转换(User-Defined Conversion) 在计算机语言中,类型的存在让我们可以更有针对性的进行数据和功能的处理,但是却又存在了类型转化的问题.C++如同其他计算机语言一样 ...

  3. cala中隐式转换(implicit conversion)的优先顺序

    转 http://blog.csdn.net/nethibernate/article/details/5893184 在学习Scala的时候,隐式转换(implicit conversion)这个特 ...

  4. C++转换函数 (conversion function)

    本文将介绍C++中的转换函数(conversion function). 1.代码 设计一个类Fraction表示分数,包含分子和分母.我们希望它能自动转换为double类型,并参与运算. Fract ...

  5. Mcad学习笔记之委托再理解(delegate的构造器,MulticastDelegate,BeginInvoke,EndInvoke,Invoke4个方法的探讨)...

    相关文章导航 Sql Server2005 Transact-SQL 新兵器学习总结之-总结 Flex,Fms3相关文章索引 FlexAir开源版-全球免费多人视频聊天室,免费网络远程多人视频会议系统 ...

  6. C#委托的介绍(delegate、Action、Func、predicate)

        (a).  delegate: delegate我们常用到的一种声明   Delegate至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型.   例:public delega ...

  7. IOS消息机制-委托(ptotocol与delegate)

    protocal : 协议,protocal是一种语法,提供统一的接口给遵守协议的类使用. delegate : 委托,是Coaoa中常用的一种设计模式,把自己的类需要做的一些事情委托给另一个类去做, ...

  8. c# 带返回值的action_C#委托的介绍(delegate、Action、Func、predicate)

    委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.事件是一种特殊的委托. 1.委托的声明 (1). delegate delegate我们常用到的一种声明 Delegat ...

  9. 多播委托(multicast delegate)

    还是老规矩,先看代码:) using System; class MulticastTester {     delegate void Greeting();          public sta ...

  10. 委托和事件[delegate and event]_C#

    委托和事件: 1. 委托:一个能够表示方法的数据类型:它将方法作为对象封装起来,允许在运行时间接地绑定一个方法调用. 2. 声明委托数据类型: public delegate  bool Greate ...

最新文章

  1. Visual Studio 2019更新到16.2.3
  2. matlab与quartus的联合数据交换(NCO与文件数据的混频处理)
  3. 微信jssdk 图片上传 JAVA_微信jssdk图片上传
  4. 蚂蚁前端的开局十年:一切都在路上
  5. python项目构建_通过构建4个项目来学习Python网络
  6. BBC纪录片任正非谈创业:华为是谁?
  7. 让DB2跑得更快——DB2内部解析与性能优化
  8. 0302-软件工程第一次作业
  9. python or 和and的优先级_python中not、and和or的优先级与详细用法介绍
  10. 计算机abc分类法,ABC分类法.ppt
  11. div之间横竖方向的5px间距
  12. linux ftp lcd 命令,Linux FTP命令使用实例
  13. 计算机怎样使操作家长控制,孩子自制力差 电脑设置家长控制技巧图文详细教程...
  14. elasticsearch进阶(3)—— ilm policy
  15. iphone 程购买实现
  16. 布袋除尘器--预喷涂
  17. 位图(BMP)文件格式(一)
  18. 起诉传音,华为为何会对一张壁纸要价2000万?
  19. ModuleNotFoundError: No module named ‘sentence_transformers‘
  20. Type-challenges类型体操 1097-IsUnion 题解

热门文章

  1. 万恶之源-python加深
  2. 加法器php,全加器原理是什么
  3. 关于VirtualBox运行出现“0x00000000指令引用的0x00000000内存。该内存不能为written”的解决方法
  4. shell脚本快速执行命令
  5. Windows7旗舰版安装 Anaconda3 详细图文教程
  6. 亚洲前沿科技展望:人工智能与区块链的融合发展
  7. MAC装虚拟机显示打不开 /dev/vmmon: 断裂管道 请确保已载入内核模块 ’vmmon’
  8. 手机连Fiddler后,仍然不能上网的解决办法
  9. 【QT】对话框dialog
  10. powershell为所有用户卸载磁贴应用