惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
Last Week in AI
Last Week in AI
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
H
Help Net Security
F
Fortinet All Blogs
MyScale Blog
MyScale Blog
宝玉的分享
宝玉的分享
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 司徒正美
量子位
N
Netflix TechBlog - Medium
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
Recorded Future
Recorded Future
博客园 - 三生石上(FineUI控件)
Vercel News
Vercel News
aimingoo的专栏
aimingoo的专栏
I
InfoQ
Microsoft Security Blog
Microsoft Security Blog
Scott Helme
Scott Helme
The Last Watchdog
The Last Watchdog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
IT之家
IT之家
AI
AI
WordPress大学
WordPress大学
Security Archives - TechRepublic
Security Archives - TechRepublic
Google Online Security Blog
Google Online Security Blog
U
Unit 42
V2EX - 技术
V2EX - 技术
MongoDB | Blog
MongoDB | Blog
Schneier on Security
Schneier on Security
博客园 - Franky
H
Heimdal Security Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Jina AI
Jina AI
W
WeLiveSecurity
P
Privacy & Cybersecurity Law Blog
Cloudbric
Cloudbric
B
Blog RSS Feed
N
News | PayPal Newsroom
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
I
Intezer
Hacker News - Newest:
Hacker News - Newest: "LLM"
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园_首页
罗磊的独立博客
H
Hackread – Cybersecurity News, Data Breaches, AI and More
雷峰网
雷峰网

博客园 - Felix Liang

精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件 精进 Spring Boot 02 | Spring Boot 的文档结构、POM 文件格式的介绍,以及 Maven 的使用。 精进 Spring Boot 01 | Spring Boot 入门,用 Spring Boot 写第一个 Hello World How do I get started with Node.js 修改xampp的mysql默认密码和端口 Visual Studio 2013 错误系统找不到指定文件,0x80070002 Daily Build H公司数据同步的总结 VB2010新特性之——标识语言版本的新命令行选项/langversion (Visual Basic) 为什么开发人员不能估算时间? [翻译]SQL Server 未公开的两个存储过程sp_MSforeachtable 和 sp_MSforeachdb 获取应用程序的根Url - Felix Liang - 博客园 Lambda 表达式 Lambda Expressions (Visual Basic) 集合初始化器概览(Visual Basic) VB2010 的隐式续行(Implicit Line Continuation) 自动实现属性 Visual Basic 2010 新特性 VS2008 Tips #009 – 您可以在 ASP.NET 的 Web.config 文件中注册用户控件 VS2008 Tips #008 如何创建ASP.NET Web 用户控件并包含在Web 页面中 - Felix Liang
宽松委托转换(Relaxed delegate conversion)
Felix Liang · 2010-05-18 · via 博客园 - Felix Liang

宽松委托转换(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 IntegerAs Integer' Option Strict 为 on 或 off, 都是正确的 lambda 表达式赋值

      
' 整型匹配
      Dim d1 As Del1 = Function(m As Integer3' Integer 扩大为 Long
      Dim d2 As Del1 = Function(m As Long3' Integer 扩大为 Double
      Dim d3 As Del1 = Function(m As Double3

   
      只有 

Option Strict 设置为 Off 的时候,才允许缩小转换(Narrowing conversion。    
    
' 仅当 Option Strict 为 off 才正确:

      
Dim d4 As Del1 = Function(m As StringCInt(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 DoubleCByte(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 IntegerCLng(n)

忽略参数规格

宽松委托(Relaxed delegate)允许您完全忽略赋值方法(assigned method)的参数规格

' 定义委托 Del2, 带两个参数
Delegate Function Del2(ByVal arg1 As Integer, ByVal arg2 As StringAs 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 SubSub 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 IntegerAs Integer' Definitions of f1, f2, f3, and f4.
Function f1(ByVal m As IntegerAs Integer
End FunctionFunction f2(ByVal m As LongAs Integer
End FunctionFunction f3(ByVal m As IntegerAs Short
End FunctionFunction 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 IntegerAs 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))