关于委托,肯定是要有问题的。
关于事件。
关于Lambda。
由上面的那个伪代码就能看得出来,委托其实是和类在一个层次的东西,它还有基类,两个基类:System.MulticastDelegate和System.Delegate基类。简单的委托实例(两个数的加法):
怎么干?委托在底层,实际上在MulticastDelegate派生类上调用了编译器生成的invoke方法。说下委托的类型安全:如果试图将一个不匹配的方法传入委托,就会收到编译错误(例如上面的委托你传入一个参数的方法。)
定义委托,来判断,当加速的时候,会不会超过最大值而崩溃:
下面是加速方法,当速度不同的时候输出一些不同的信息:
在PRogram的Main方法里面每次加速 二十,并且记录每次加速之后的输出:
调用结果如下:
由上,可以总结出委托通知的步骤:定义将通知发送给调用者的委托类型。声明每个委托类型成员变量。在泪殇创建辅助函数使调用者能指定由委托成员变量保存的方法。修改方法,在适当的情形下调用委托中的调用列表。
Car中的方法修改:
调用代码:
结果:
同理,如果是想要移除方法,用-=操作符就可以了。相当于退订功能。
泛型委托提供了更灵活的方式来指定类型安全的形式进行调用的方法。之前,我们一般通过使用System.Object参数来达到相似的目的:public delegate void MyDelegate(object arg);尽管如此,但是我们会因此失去类型安全并且可能还会有装箱损失。
下面是修改之后的加速方法:
由此可以看来,事件只是节省了键入事件,下面说说如何在调用者这边监听传入的事件。C#事件也简化了注册调用者事件处理程序的操作。现在无需指定自定义辅助方法,调用者仅需使用+=和-=操作符即可(操作符将在后台触发正确的add_xxx()方法或remove_xxx()方法)。使用C#的事件注册语法修改Main方法如下:
当然,我们也可以用方法组转换语法。就不再陈述。
所以,如果我们如果要传递自定义数据,那么就需要创建一个派生自EventArgs的类。如下:
我们修改委托,增添一个CarEventArgs参数,就可以传递数据了。(事件不变。)public delegate void CarEngineHandler(object sender, CarEventArgs args);//定义委托调用方法: if (Exploded != null) { Exploded(this,new CarEventArgs("Sorry, this car is dead...")); }如何接受者想与发送事件的对象交互,我们可以现实强制转换System.Object。这样就可以使用传递给事件通过对象中的任何公共成员。
匿名方法非常有趣,它使我们能访问定义他们的方法的本地变量。这些变量成为匿名方法的外部变量。有关匿名方法和定义方法的作用域之间的交互,有几个重要的知识点:匿名方法不能访问定义方法中的ref或out参数。匿名方法中的本地变量不能与外部方法中的本地变量重名。匿名方法可以访问外部类作用域中的实例变量(或静态变量)。新闻热点
疑难解答