Runtime(运行时)提供两个机制:一个机制能通知发生了紧急事件;另一个机制则规定在发生事件时应该允许什么方法,这正是事件和委托的用途。
委托(delegate):是指向一个方法指针,通过指定一个委托名称,即可通过委托来调用方法,即可将方法当作参数传递。
自定义委托:
delegate void stopAlarmDelegate();//定义委托以Delegate结尾
privarte stopAlarmDelegate stopAlarm;
public main()
{
this.stopAlarm+=ShutDownAlarm;//创建委托实例
}
private ShutDownAlarm()
{
//执行方法
}
C#预定义的委托:
Action:无返回值的泛型委托,至少0个参数,至多16个参数
Func:有返回值的泛型委托,至少0个参数,至多16个参数,最后一个参数类型为返回类型
predicate:返回bool型的泛型委托,有且只有一个参数,返回值固定为bool
//Action委托
public void Test<T>(Action<T> action,T p)
{
action(p);
}
//Action实例
public Action<string> LoginSuccessEvent+=LoginSuccess;
private void LoginSuccess(string username)
{
//执行方法
}
//执行委托
if(LoginSuccessEvent!=null)LoginSuccessEvent.Invoke(username);//LoginSuccessEvent(username)
//Func委托
public int Test<T1,T2>(Func<T1,T2,int>func,T1 a,T2 b)
{
return func(a, b);
}
//Predicate委托
public delegate bool Predicate<T> (T obj)
事件: 事件在类中声明且生成,且通过使用同一个类或其他类中的委托与事件处理程序关联。包含事件的类用于发布事件。这被称为 发布器(publisher)类。其他接受该事件的类被称为 订阅器(subscriber)类。
//事件实例1
public class EventClass
{
public delegate void StopAlarmEventHandler(object serder, EventArgs e);
public event StopAlarmEventHandler StopAlarmEvent;
}
main()
{
EventClass eventClass=new EventClass();
eventClass.StopAlarmEvent+=new EventHandler(StopAlarm);
public void StopAlarm(object sender, EventArgs e)
{
//执行方法
}
}
//事件实例2
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 );
}
}
Windows事件原理:事件的前生是message,Windows是消息驱动的操作系统,当你在窗体上点击左键时,一条名为WM_LBUTTONDOWN消息就会加入Windows待处理的消息队列中,大部分情况下Windows的消息队列不会有天多消息在排队,消息会立即被处理,如果你的计算机很慢或在很忙状态,那么消息要等会才能被处理,就就是系统反应迟钝的原因,当Windows处理到这条消息时会把消息发送给单击窗体,窗体会用自己的一套算法来响应这个消息,这个算法就是Windows API开发中说的消息处理函数。消息处理函数中有个多级嵌套的switch结构,进入这个switch结构的消息会被分门别类并最终流入某个末端分支,在这个末端分支会有一个由程序员编写的函数被调用。