收藏 分享(赏)

C#培训资料第十五章.ppt

上传人:kpmy5893 文档编号:10108036 上传时间:2019-10-10 格式:PPT 页数:23 大小:142.50KB
下载 相关 举报
C#培训资料第十五章.ppt_第1页
第1页 / 共23页
C#培训资料第十五章.ppt_第2页
第2页 / 共23页
C#培训资料第十五章.ppt_第3页
第3页 / 共23页
C#培训资料第十五章.ppt_第4页
第4页 / 共23页
C#培训资料第十五章.ppt_第5页
第5页 / 共23页
点击查看更多>>
资源描述

1、第15章 委托,本章内容,什么是委托 声明委托类型 创建委托对象 赋值委托 组合委托 为委托增加方法,从委托移除方法 使用委托 委托的示例 调用带返回值的委托 匿名方法 Lambda表达式,15.1 什么是委托,委托是具有相同签名和返回值类型的有序方法列表的对象。 方法列表称为调用列表。 当委托被调用时,它调用列表中的每一个方法。 单个方法的委托和C+的函数指针类似。委托是面向对象的并且是类型安全的。 方法可以是来自任何类或结构,只要他们同时匹配委托的如下两点:返回值和签名。调用列表中的方法可以是实例方法或者静态方法。,15.2 声明委托类型,委托是类型,就好像类是类型一样。委托类型必须在被用

2、来创建变量以及类型的对象之前声明。委托类型声明和所有类型声明一样,不需要在类的内部进行声明: delegate void mydel(int x); 委托类型声明看上去与方法的声明很相似,有返回值和签名。返回类型和签名指定了委托接受的方法的形式。例如上面的例子声明指定了这种类型的委托只会接受不返回值并且由单个int参数的方法。 委托类型声明在两个方面与方法声明不同: 以delegate关键字开头。 没有方法主体。,15.3 创建委托对象,委托是引用类型因此有引用和对象。在委托类型声明之后,我们可以声明变量并创建类型的对象。如下表是委托类型的变量声明:medel delvar; 有两种创建委托对

3、象的方式,第一种是使用带new的运算符的对象创建表达式:委托类型名,一组圆括号,其中包含作为调用列表中的一个成员的方法的名字。方法可以是实例方法或静态方法。delvar=new mydel(myinstobj.mym1); 我们还可以使用快捷语法,它仅仅由方法说明符构成,使用快捷语法是因为在方法名称和其相应的委托类型之间有隐式转换。delvar=myinstobj.mym1; 例子:delegate void mydel(int x);/声明委托类型 mydel delvar,dvar;/创建两个委托变量 delvar=new mydel (myinstobj.mym1);/创建委托并保存使用

4、 mydel dvar = SClass.otherM2;/创建委托并保存使用,15.4 赋值委托,由于委托是引用类型,我们可以通过给他赋值来改变包含在委托变量中的引用。旧的委托对象会被垃圾回收器回收。 例如: Mydel delvar; delvar=myinstobj.mym1; Delval=sclass.otherm2;,15.5 组合委托,我们见过的委托在调用列表中都只有一个方法。委托可以使用额外的运算符来“组合”。这个运算符最终会创建一个新委托,例如: Medel dela=myinstobj.mym1; Medel delb=sclass.otherm2; Medel delc=

5、dela+delb; 尽管组合委托往我们觉得好像操作数委托被修改了,其实他们并没有被修改,委托是很顶的。委托对象被创建之后就不会再被改变。,15.6 为委托增加方法,通过上一节我们知道委托其实是不变的,但是C#提供了为委托增加方法的语法。例如: Mydel delvar=inst.mym1;/创建并初始化 Delvar+=scl.m3;/增加方法 Delvar+=x.act;/增加方法 当然,在使用+=运算符时,实际发生的是创建一个新委托,其调用列表是委托加上方法的组合。,15.7 从委托中移除方法,我们还可以使用-=运算符从委托中移除方法,例如: Delvar-=scl.m3; 与委托增加方

6、法一样,其实是创建了一个新的委托。新的委托是旧委托的副本,只是没有了已经被移除方法的引用。但是移除的时候应该注意以下事项: 如果在调用列表中的方法有多个实例,-=将从列表最后开始搜索,并且移除第一个与方法匹配的实例。 试图删除委托中不存在的方法是没有效果的。 试图调用空委托会抛出异常。 我们可以通过把委托和null进行比较来判断委托的调用列表是不是为空。如果调用列表为空泽委托为null。,15.8 调用委托,可以像调用方法一样简单的调用委托,用于调用委托的参数将会用于调用调用列表中的每一个方法(除非有一个参数是输出参数)。例如: Mydel delvar=inst.mym1; delvar+=

7、scl.m3; delvar+=x.act; delvar(55);/调用委托 一个方法可以在调用列表中出现多次。这样,当委托被调用时,每次在列表中遇到这个方法时,他就会被调用一次。,15.9 委托的示例,Class text public void print1() Public static void print2() Static void main() text t=new text();/创建一个测试类实例 Printfunction pf;/创建一个空委托 Pf=t.print1; /实例化并初始化该委托 Pf+=text.print2; Pf+=t.print1; Pf+=tex

8、t.print2; If(null!=pf) /确认委托有方法 Pf(); /调用委托 ,右侧的代码执行之后先后调用了方法print1, print2, print1, print2,15.10 调用带返回值的委托,若委托有返回值并且在调用列表中有一个以上的方法,会发生以下情况: 调用列表中最后一个方法返回值就是委托调用返回的值。 调用列表中所有其他方法的返回值都会被忽略。 来看例子: delegate int mydel; class myclassint i=5; public int add2()i+=2;return i; public int add3()i+=3;return i;

9、 static void main() myclass mc=new myclass(); mydel mdel=mc.add2;mdel+=mc.add3; mdel+=mc.add2; Console.writeline(“value:0”,mdel(); ,5.11 调用带引用参数的委托,若果委托中有引用参数,参数值就会根据调用列表中的一个或多个方法返回值而改变。在调用委托列表中的下一个方法时,参数的新值会传给下一个方法。例如: delegate viod mydel(ref int i); class myclass public int add2(ref int i)i+=2;ret

10、urn i; public int add3(ref int i)i+=3;return i; static void main() myclass mc=new myclass(); mydel mdel=mc.add2;mdel+=mc.add3; mdel+=mc.add2; Int x=5; mdel(ref x); Console.writeline(“value:0”,mdel(); ,15.12 匿名方法(不讲,不建议使用),至此,我们已经见过了使用静态方法或实例方法来初始化委托。对于这种情况,方法本身可以被代码的其他。部分显式调用,当然,也就必须是某个类或结构的成员。 然而,若

11、方法只会被使用一次用来初始化委托会怎么样呢?在这种情况下,除了创建委托语法的需要,没有必要使用独立的具名方法。匿名方法允许我们使用独立的具名方法。 匿名方法:是在初始化委托时内联声明的方法。,15.12.1 使用匿名方法,我们可以在如下地方使用匿名方法: 声明委托变量时作为初始化表达式。 组合委托时在赋值语句的右边。 为委托增加事件时在赋值语句的右边。,返回类型,匿名方法不会显式声明返回值。然而,实现代码本身的行为必须通过返回一个在类型上与委托的返回类型相同的值来匹配委托的返回类型。若果委托有void类型的返回值,匿名方法就不能返回值。 例如,在如下代码中,委托的返回类型是int。匿名方法的实

12、现代码因此也必须在代码的路径中返回int。 delegate int otherdel(int inparam) static void main() otherdel del=delegate(int x) return x+20; ; ,参数,除了数据参数,匿名方法的参数列表必须在如下三个方面匹配委托: 参数数量。 参数类型。 修饰符。 我们可以使用圆括号为空或者简化圆括号来简化匿名方法的参数列表,但是仅在下面两项都为真的情况下才能这样做: 委托的参数列表不包含任何out参数。 匿名方法的使用任何参数。 例如: Delegate void somedel(int x) Somedel sd

13、el=delegate Printmessage(); Cleanup();,Params 参数,如果委托声明的参数列表包含了params参数,哪么params关键字就会被匿名方法的参数列表忽略。例如,在如下代码中: 委托类型声明制定最后一个参数为params类型参数; 然而,匿名方法参数列表忽略了params关键字。 delegate void somedel(int x,params int y); somedel mdel =delegate(int x,inty) ;,15.12.3 变量和参数的作用域,参数以及生命在匿名方法内部的局部变量的作用域在实现方法的主体之内 delegate

14、 void mydel(int x); Mydel mdel=delegate(int y) Int z=10; Console.writeline(“0,1”,y,z); /y和z的作用域结束 Console.writeline(“0,1”,y,z);/编译错误,外部变量和生命周期的扩展,与委托的命名方法不同,匿名方法可以访问他们外围作用域的局部变量和环境: 外围作用域的变量叫做外部变量。 用在匿名方法实现代码中的外部变量称为方法捕获。 只要不活方法还是委托的一部分,即使变量已经离开作用域,被捕获的外部对象也会一直有效。,15.13 Lambda表达式,匿名方法的语法有点麻烦并且需要一些编译

15、器已经知道的信息,而引入Lambda表达式简化了匿名方法的语法。按以下步骤将匿名方法转化为Lambda表达式: 删除delegate关键字。 在参数列表和匿名方法主体之间放Lambda 运算符=,读作goes to。 例如: Mydel del=delegate(int x)return x+1;/匿名方法 Mydel lel=(int x) = return x+1;/ Lambda表达式,进一步简化,例子如下: Mydel del=delegate(int x)return x+1;/匿名方法 Mydel le1=(int x) = return x+1;/ Lambda表达式 Mydel le2 =( x) = return x+1;/ Lambda表达式 Mydel le3 = x = return x+1;/ Lambda表达式 Mydel le4 =x= x+1;/ Lambda表达式,参数列表的要点,有关lambda的表达式的参数列表的要点如下: lambda的表达式的参数列表中的参数必须在参数数量,类型和位置上与委托相匹配。 表达式的参数列表中的参数不一定需要包含类型(如隐式类型),除非委托有ref或者out参数此时类型是必须的。 如果只有一个参数,并且是隐式类型的,周围的圆括号可以省略否则他是必须的。 如果没有参数,必须使用一组空的圆括号。,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报