《Illustrated C# 2012, 4th Edition》Daniel M. Solis 第13章 委托 笔记

委托

需要先声明委托类型,再使用这个委托类型声明委托对象。
委托类型使用delegate关键字声明。
委托类型不需在类或结构体内声明。

委托是持有0或1或多个方法的对象,执行委托时,委托执行它持有的方法。
委托持有的方法必须与委托类型的函数签名,返回值类型都相同。
委托持有的方法可以是静态方法。

委托对象可以使用new关键字初始化,也可以使用快捷语法:

delVar = new MyDel( myInstObj.MyM1 );
dVar = new MyDel( SClass.OtherM2 );
delVar = myInstObj.MyM1;
dVar = SClass.OtherM2;

组合委托(combining delegate):

MyDel delA = myInstObj.MyM1;
MyDel delB = SClass.OtherM2;

MyDel delC = delA + delB;

但委托对象在初始化之后就不再改变,改变的只是它持有的方法列表:

委托支持通过+=和-=运算符添加和删除持有的方法。
-=运算符从调用列表末尾开始搜索,删除第一个匹配的方法。如果不存在匹配的方法,没有效果。

执行调用列表为空的委托会抛出异常。
委托可以通过与null比较,判断方法列表是否为空。

当一个方法在调用列表中出现多次,执行委托时会执行多次。

执行委托时传递的参数,会传递给每一个它持有的方法。

执行带返回值的委托,返回调用列表中最后一个方法的返回值。
执行带引用参数的委托,调用时调用列表中下一个方法使用上一个方法调用结束时参数的值。

匿名方法(anonymous method)

声明委托对象作为初始化表达式,为委托对象赋值时在=和+=运算符的右边,可以使用匿名方法。

匿名方法由delegate关键字、参数列表、方法体组成。
匿名方法不声明返回值类型,返回值类型对应委托的返回值类型。
匿名方法的参数列表必须与对应的委托相匹配。

  1. 当委托的参数列表不包含out参数,同时匿名方法不使用任何参数时,参数列表可以只保留圆括号或完全省略。
  2. 当委托的参数列表包含params参数,匿名方法中params关键字必须省略。

在匿名方法中支持访问外部作用域的变量。

  1. 匿名方法外的这个变量为外部变量(outer variable)
  2. 匿名方法内的这个变量为被方法捕获(capured)。
  • 被捕获的变量的生命周期被延长。

Lambda表达式

C# 3.0进入Lambda表达式替代C# 2.0引入的匿名方法。
Lambda表达式不使用delegate关键字,使用Lambda运算符=>,读作“goes to”。

Lambda表达式允许在不包含ref或out参数时,省略形参的类型名。当只有一个形参时,并且省略了类型名,可以省略圆括号。当方法体只包含一条return语句时,支持使用return语句中的表达式替代方法体。