C#中委托和事件的区别
大抵来说,委托是一个类,该类外部保护着一个字段,指向一个办法。事件能够被看作一个委托类型的变量,通过事件注册、勾销多个委托或办法。本篇别离通过委托和事件执行多个办法,从中领会两者的区别。

□ 通过委托执行办法

class Program{    static void Main(string[] args)    {        Example example = new Example();        example.Go();        Console.ReadKey();    }}public class Example{    public delegate void DoSth(string str);    internal void Go()    {        //申明一个委托变量,并把已知办法作为其构造函数的参数        DoSth d = new DoSth(Print);        string str = "Hello,World";        //通过委托的静态方法Invoke触发委托        d.Invoke(str);    }    void Print(string str)    {        Console.WriteLine(str);    }}

以上,

○ 在CLR运行时,委托DoSth实际上就一个类,该类有一个参数类型为办法的构造函数,并且提供了一个Invoke实例办法,用来触发委托的执行。
○ 委托DoSth定义了办法的参数和返回类型
○ 通过委托DoSth的构造函数,能够把合乎定义的办法赋值给委托
○ 调用委托的实例办法Invoke执行了办法

但,实际上让委托执行办法还有另外一种形式,那就是:委托变量(参数列表)

public class Example{    public delegate void DoSth(object sender, EventArgs e);    internal void Go()    {        //申明一个委托变量,并把已知办法作为其构造函数的参数        DoSth d = new DoSth(Print);        object sender = 10;        EventArgs e = new EventArgs();        d(sender, e);    }    void Print(object sender, EventArgs e)    {        Console.WriteLine(sender);    }}

以上,

○ 委托DoSth的参数列表和办法Print的参数列表还是保持一致
○ 委托DoSth中的参数object sender通常用来示意动作的发起者,EventArgs e用来示意动作所带的参数。

而实际上,委托变量(参数列表),事件就是采纳这种模式执行办法的。

□ 通过事件执行办法

public class Example{    public delegate void DoSth(object sender, EventArgs e);    public event DoSth myDoSth;    internal void Go()    {        //申明一个委托变量,并把已知办法作为其构造函数的参数        DoSth d = new DoSth(Print);        object sender = 10;        EventArgs e = new EventArgs();        myDoSth += new DoSth(d);        myDoSth(sender, e);    }    void Print(object sender, EventArgs e)    {        Console.WriteLine(sender);    }}

以上,

○ 申明了事件myDoSth,事件的类型是DoSth这个委托
○ 通过+=为事件注册委托
○ 通过DoSth委托的构造函数为事件注册委托实例
○ 采纳委托变量(参数列表)这种模式,让事件执行办法

而且,通过+=还能够为事件注册多个委托。

public class Example

{    public delegate void DoSth(object sender, EventArgs e);    public event DoSth myDoSth;    internal void Go()    {        //申明一个委托变量,并把已知办法作为其构造函数的参数        DoSth d = new DoSth(Print);        DoSth d1 = new DoSth(Say);        object sender = 10;        EventArgs e = new EventArgs();        //为事件注册多个委托        myDoSth += new DoSth(d);        myDoSth += new DoSth(d1);        myDoSth(sender, e);    }    void Print(object sender, EventArgs e)    {        Console.WriteLine(sender);    }    void Say(object sender, EventArgs e)    {        Console.WriteLine(sender);    }}

以上,通过+=为事件注册1个或多个委托实例,实际上,还能够为事件间接注册办法。

public class Example{    public delegate void DoSth(object sender, EventArgs e);    public event DoSth myDoSth;    internal void Go()    {        object sender = 10;        EventArgs e = new EventArgs();        //为事件注册多个委托        myDoSth += Print;        myDoSth += Say;        myDoSth(sender, e);    }    void Print(object sender, EventArgs e)    {        Console.WriteLine(sender);    }    void Say(object sender, EventArgs e)    {        Console.WriteLine(sender);    }}    

□ 通过EventHandler执行办法

先来看EventHandler的源代码。

1

可见,EventHandler就是委托。当初就应用EventHandler来执行多个办法。

public class Example{    public event EventHandler myEvent;    internal void Go()    {        object sender = 10;        EventArgs e = new EventArgs();        //为事件注册多个委托        myEvent += Print;        myEvent += Say;        myEvent(sender, e);    }    void Print(object sender, EventArgs e)    {        Console.WriteLine(sender);    }    void Say(object sender, EventArgs e)    {        Console.WriteLine(sender);    }}

总结:
○ 委托就是一个类,也能够实例化,通过委托的构造函数来把办法赋值给委托实例
○ 触发委托有2种形式: 委托实例.Invoke(参数列表),委托实例(参数列表)
○ 事件能够看作是一个委托类型的变量
○ 通过+=为事件注册多个委托实例或多个办法
○ 通过-=为事件登记多个委托实例或多个办法
○ EventHandler就是一个委托