《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关键字、参数列表、方法体组成。
匿名方法不声明返回值类型,返回值类型对应委托的返回值类型。
匿名方法的参数列表必须与对应的委托相匹配。
- 当委托的参数列表不包含out参数,同时匿名方法不使用任何参数时,参数列表可以只保留圆括号或完全省略。
- 当委托的参数列表包含params参数,匿名方法中params关键字必须省略。
在匿名方法中支持访问外部作用域的变量。
- 匿名方法外的这个变量为外部变量(outer variable)
- 匿名方法内的这个变量为被方法捕获(capured)。
- 被捕获的变量的生命周期被延长。
Lambda表达式
C# 3.0进入Lambda表达式替代C# 2.0引入的匿名方法。
Lambda表达式不使用delegate关键字,使用Lambda运算符=>,读作“goes to”。
Lambda表达式允许在不包含ref或out参数时,省略形参的类型名。当只有一个形参时,并且省略了类型名,可以省略圆括号。当方法体只包含一条return语句时,支持使用return语句中的表达式替代方法体。