C#的事件与委托
目录
-
事件概念(Event):所谓的事件是指用户的操作,或者是一些提示信息等等。应用程序需要在事件发生时响应事件。C#中使用事件机制实现线程间的通信。
-
事件在类中声明且生成,且通过使用同一个类或其他类中的委托与事件处理程序关联。包含事件的类用于发布事件。这被称为 发布器(publisher) 类。其他接受该事件的类被称为 订阅器(subscriber) 类。事件使用 发布-订阅(publisher-subscriber) 模型。
发布器(publisher) 是一个包含事件和委托定义的对象。事件和委托之间的联系也定义在这个对象中。发布器(publisher)类的对象调用这个事件,并通知其他的对象。
订阅器(subscriber) 是一个接受事件并提供事件处理程序的对象。在发布器(publisher)类中的委托调用订阅器(subscriber)类中的方法(事件处理程序)。 -
[声明事件:]
在类的内部声明事件,首先必须声明该事件的委托类型,e.gpublic delegate void BoilerLogHandler(string status);然后,声明事件本身,使用 event 关键字,
// 基于上面的委托定义事件
public event BoilerLogHandler BoilerEventLog;
上面的代码定义了一个名为 BoilerLogHandler 的委托和一个名为 BoilerEventLog 的事件,该事件在生成的时候会调用委托,委托调用订阅器里面的方法(事件处理程序处理事件)。 -
[插入一个小片段----Virtual(虚方法):]
virtual关键字用于在基类中修饰方法。virtual的使用会有两种情况:
情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法。那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法。
情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法。那么在对派生类实例的调用中,该虚方法使用的是派生重写的方法。
代码示例一:
using System;
namespace SimpleEvent
{
/发布器类/
public class EventTest
{
private int value;public delegate void NumManipulationHandler();
public event NumManipulationHandler ChangeNum;
protected virtual void OnNumChanged()
{
if ( ChangeNum != null )
{
ChangeNum(); /* 事件被触发 /
}else {
Console.WriteLine( "event not fire" );
Console.ReadKey(); / 回车继续 */
}
}public EventTest()
{
int n = 5;
SetValue( n );
}public void SetValue( int n )
{
if ( value != n )
{
value = n;
OnNumChanged();
}
}
}/订阅器类/
public class subscribEvent
{
public void printf()
{
Console.WriteLine( "event fire" );
Console.ReadKey(); /* 回车继续 */
}
}/触发/
public class MainClass
{
public static void Main()
{
EventTest e = new EventTest(); /* 实例化对象,第一次没有触发事件 /
subscribEvent v = new subscribEvent(); / 实例化对象 /
e.ChangeNum += new EventTest.NumManipulationHandler( v.printf ); / 注册 */
e.SetValue( 7 );
e.SetValue( 11 );
}
}} -
[代码解析与延伸:]
e.g:ChangeNum += new EventTest.NumManipulationHandler( v.printf ); /* 注册 */
解析1:-->这里就是简单的给事件赋值操作而已;new EventTest.NumManipulationHandler( v.printf )-->事件的处理程序通过委托去调用;老的C#版本中会这样去调用,在如今的C#版本中,使用的是直接把事件处理方法赋值给事件--e.g ChangeNum = v.printf ;此外,还有一个点要注意,把方法传给委托时,方法的参数列表和返回值类型和委托的一致才可以。
e.g:public event NumManipulationHandler ChangeNum;
延伸1:event NumManipulationHandler可理解为一种类型,在C#新发布的版本中,可以用Action来代替传统的委托声明方式,e.g:public delegate int NumManipulationHandler();等效于public Action ChangeNum;
延伸2.以前为了能调用一个方法,必须定义一个相应的delegate,后来便有了通用委托Func<>,方便多了。没有参数: Func;有参数:Func<T,TResult>,T代表传入参数类型,TResult代表返回参数类型,当然可以有多个参数T1、T2、T3…
延伸3.Action的用法与Func几乎一样,调用方法也类似,两者都支持Lambda表达式。
延伸4:Func与Action的区别
Func与Action作用几乎一样。只是Func有返回类型;Action 只有参数类型,不能传返回类型。所以Action 的委托函数都是没有返回值的。
posted on 2019-07-26 19:43 NoMatterTryAgain 阅读(314) 评论(0) 收藏 举报
浙公网安备 33010602011771号