《C#图解教程》读书笔记第15章——委托

这本书讲解 C# 语言十分详细,我将其中的重要内容整理成条款,以备忘。

 

1.       同类是一种类型一样,委托也是一种类型 。委托对象包含有相同签名 ( 包括 ref out 修饰符 ) 相同返回值类型有序方法列表 。方法列表叫做调用列表,当委托被调用时,将调用列表中的每一个方法。

 

2.       调用列表中的方法可以是静态 方法也可以是实例 方法。委托是引用 类型,因此有引用和对象,在委托类型声明后,可以声明引用变量并创建类型的对象。

 

3.       委托对象的创建及初始化方法有两种: MyDel  delVar = new MyDel(myInstObj.MyMethod); 括号中内容的是作为调用列表中第一个成员的方法的名字。还可以使用快捷语法 MyDel  delVar = myInstObj.MyMethod;( 推荐使用,使代码更加简洁 ) ,此语句和前一句等价,都会创建一个委托对象 并保存它的引用。

 

4.       可以给委托变量赋值以改变包含在变量中的引用。可以使用 + - 运算符来对委托进行组合或拆分,这个运算符会创建一个 的委托对象 ,它的调用列表是两个操作数委托调用列表副本的连接。注意:操作数委托没有被修改,委托对象是恒定的,一旦创建后不会被改变。

 

5.       可以使用 += 操作符为委托增加方法,如:

MyDel delVar = inst.MyM1;

delVar += SC.m2;

delVar += X.Act;

每次调用 += 运算符时,其实都是创建了一个新的委托对象 ,并将引用指向新的对象,这个对象的调用列表是左边委托中的调用列表加上右边方法的组合。旧的委托对象会被垃圾收集器回收。

 

6.       同时还可以用 -= 来为委托移除方法,同样也是每次创建一个新的委托对象 ,它是旧对象的副本,只是没有了已经被移除的方法的引用。如果调用列表中的方法有多个实例, -= 运算符将从列表最后 开始搜索,并移除第一个与方法匹配的实例;调用空委托会抛出异常 ,所以通常使用 null 和委托进行比较来判断委托的调用列表是否为空,若调用列表为空,则委托为 null

 

7.       使用委托像调用方法一样,用于调用委托的参数会被用于调用列表中的每一个方法。同样地,一个方法可以在调用列表中出现多次,当委托被调用时,每次在列表中遇到这个方法时它都会被调用一次。

 

8.       如果委托调用列表中有一个以上带返回值的方法时,表中最后一个方法的返回值 就是委托调用的返回值 ,其他方法的返回值都会被忽略。

 

9.       如果委托有引用 (ref) 参数,参数值会根据调用列表中前一个方法的返回值而改变 ,在调用委托列表中的下一个方法时,参数的新值 ( 即经过前一个带 ref 参数的方法处理过的值,而不是初始值 ) 会传给下一个方法。

 

10.   匿名方法 :当在方法只被使用一次时,除了创建委托语法,没必要创建单独的有名字的语法,匿名方法应运而生。匿名方法用在:声明委托变量时作为初始化表达式;组合委托和为事件增加处理程序时在赋值语句的右边。

 

11.   匿名方法语法: delegate  (Parameters)  { Statement } ; ( 注意不要丢掉分号 ) 不显式声明返回值 ,但方法体中要返回一个和委托返回值类型相同或可以隐式转换为委托的返回值类型的值 ,若委托的返回值类型为 void ,则匿名方法不能返回任何值但可以有空的 return 语句。

 

12.   匿名方法的参数应该在参数数量、类型、修饰符上和委托匹配,如果下面两项 符合: 1. 委托的参数列表不包含任何 out 参数 ( 因为 out 参数用来在方法中向外传出数据,所以如果有 out 参数则一定会在方法中有对 out 参数的写操作 ) ,此时匿名方法所对应的委托类型可以有任意个参数; 2. 匿名方法不使用任何参数 ( 即虽对应委托包含有参数但不使用 ) 。那么可以省略圆括号 来简化匿名方法的参数列表。

 

13.   省略 参数列表和参数列表为空 是两个不同的概念。省略参数列表是不写出括号,此时匿名方法表达式对应的委托可以有任意多个参数,但不能有 out 参数;而参数列表为空时需要写出括号,此时匿名方法表达式对应的委托也不能有参数。

 

14.   如果委托声明的参数列表包含了 params 参数,那么在匿名方法的参数列表中不能出现 params ,否则会产生编译错误。

 

15.   匿名方法的参数及局部变量的作用域在匿名方法体内,但匿名方法可以访问它外围作用域的局部变量。外围作用域的变量叫做外部变量,即使外部变量已经离开了它的作用域,但在其他用到此匿名方法的环境中依然可以访问这个外部变量 ( 即此匿名方法在它的环境中保留了这个外部变量 )

 

16.   C# 3.0 中的 Lambda 表达式是为了简化匿名方法的语法而创建的。从匿名方法转换到 lambda 表达式,要通过: 1. 去掉 delegate 关键字 ( 因为编译器已经知道要将方法赋值给委托 ) 2. 在参数列表和匿名方法主体之间放置 => 运算符,读作“ goes to ”。例如:

MyDel  del = delegate(int x)  { return x + 1; };

MyDel  del =       (int x) => { return x + 1; };

 

17.   由于编译器 还可以从委托声明中推断出委托类型的参数 ,所以在 lambda 表达式中可以省略参数类型带有类型 的参数列表成为显式 类型,省略类型 的为隐式 类型。

 

18.   注意: lambda 表达式参数列表中的参数必须在参数数量、类型和位置上与委托相匹配;表达式参数列表可以省略类型,但如果委托中有 ref out 参数,则必须有参数类型 ( 即显式类型 ) ;如果只有一个 参数 并且是隐式 类型的,则参数两侧的圆括号可以省略,否则必须有括号,如: MyDel  del = x => { return x + 1; } ; MyDel  del = x => x + 1 ; 如果没有参数,必须使用一组空的圆括号。语法图示可参见 P260 15-15

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值