5.自定义事件委托
多播委托
前面使用的每个委托都只包含一个方法调用。调用一个委托就调用一个方法调用。如果要通过一个委托调用多个方法,那就需要使用委托的多播特性。如果调用多播委托,就可以按委托添加次序连续调用多个方法。为此,委托的签名就必须返回void;否则,就只能得到委托调用的最后一个方法的结果,接下来看看多播实现。
namespace Multi_Delegate
{
delegate void StringProcessor();
public class Person
{
private string _Name;
public Person(string name)
{
this._Name = name;
}
public void Say()
{
Console.WriteLine("Hello my name is {0}, what's your name.\n", this._Name);
}
public void Reply()
{
Console.WriteLine("Hello my name is {0} and nice to meet you.\n", this._Name);
}
}
class Program
{
static void Main(string[] args)
{
Person Jack = new Person("Jack");
Person Oliver = new Person("Oliver");
StringProcessor sp = null;
//绑定多播方法调用
sp += Jack.Say;
sp += Oliver.Reply;
sp();
Console.ReadKey();
}
}
}
{
delegate void StringProcessor();
public class Person
{
private string _Name;
public Person(string name)
{
this._Name = name;
}
public void Say()
{
Console.WriteLine("Hello my name is {0}, what's your name.\n", this._Name);
}
public void Reply()
{
Console.WriteLine("Hello my name is {0} and nice to meet you.\n", this._Name);
}
}
class Program
{
static void Main(string[] args)
{
Person Jack = new Person("Jack");
Person Oliver = new Person("Oliver");
StringProcessor sp = null;
//绑定多播方法调用
sp += Jack.Say;
sp += Oliver.Reply;
sp();
Console.ReadKey();
}
}
}
也许有人觉得很简单,实现的确简单明了,就是通过“+”把方法调用绑定到委托变量中,如果我们用“-”就可以移除绑定到委托变量方法了。
事件
前面一直没有解释什么是事件,现在让我用一句话解释事件和委托的关系吧!
事件和委托关系就像是属性和字段的关系,为了刚好的实现OOP的编程原则,事件对委托进行了封装。
现在我们修改前面的代码,使用事件对委托进行封装。
/// 使用事件对委托进行封装
/// </summary>
public class Say
{
/// <summary>
/// 封装委托字段
/// </summary>
public static event SpeakDelegate speakDelegate;
/// <summary>
/// 调用委托具体实现方法
/// </summary>
/// <param name="name"></param>
public static void SayManager(string name)
{
speakDelegate(name);
}
}
/// <summary>
/// 客户端调用委托
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Say.speakDelegate += Program.ChineseSpeaker;
Say.speakDelegate += Program.EnglishSpeaker;
Say.SayManager("Jackson");
Console.ReadKey();
/// </summary>
public class Say
{
/// <summary>
/// 封装委托字段
/// </summary>
public static event SpeakDelegate speakDelegate;
/// <summary>
/// 调用委托具体实现方法
/// </summary>
/// <param name="name"></param>
public static void SayManager(string name)
{
speakDelegate(name);
}
}
/// <summary>
/// 客户端调用委托
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Say.speakDelegate += Program.ChineseSpeaker;
Say.speakDelegate += Program.EnglishSpeaker;
Say.SayManager("Jackson");
Console.ReadKey();

图5自定义委托
现在让我们看看编译后Say类就可以充分证明我们的结论:事件是对委托封装。

图6自定义事件编译后的代码
大家看到在编译后的代码中出现了一个私有的委托变量,然后接下是一个公用事件委托变量,这进一步说明了事件是对委托的封装。

图7自定义事件编译后MSIL代码