事件是委托的一种特殊形式,当发生有意义的事情时,事件处理对象通知过程。
我们接着上一篇的假想场景,并且假设主办方将参会者分两组进行发言,按照事件的方式进行处理。好了,code is cheap,上代码了:
类图:
代码部分:
Code
using System;
using System.Collections.Generic;
using System.Text;
namespace CsStudy
{
class EventStudy
{
/// <summary>
/// 主办方 *** 发送器,被观察对象,他负责发送消息通知参会者发言
/// </summary>
public class Sponsor
{
public delegate void LanguageSpeak(); //声明委托
public event LanguageSpeak programLs; //定义事件,当主办方“通知”发言时,触发它
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
public Sponsor(string name)
{
this.name = name;
}
public void BeginSpeak()
{
Console.WriteLine(string.Format("I'm one of the sponsors,my name is {0}.Ok,here we go.", this.name));
if (programLs != null)
{
programLs();
}
}
public void EndSpeak()
{
Console.WriteLine(string.Format("I'm {0},thank you for your excellent report.", this.name));
}
}
/// <summary>
/// 编程语言抽象类
/// </summary>
abstract class ProgramLanguage
{
public Sponsor sponsor;
public string name;
public ProgramLanguage(string name,Sponsor sponsor)
{
this.name = name;
this.sponsor = sponsor;
}
public abstract void Speak();
}
/* 被邀请发言的编程语言包括java,javascript,c,c# , 接收器,主办方一有“通知”,他们就发言*/
class Java : ProgramLanguage
{
public Java(string name,Sponsor sponsor)
: base(name,sponsor)
{
sponsor.programLs += this.Speak; //在构造函数里注册事件处理程序
}
public override void Speak()
{
Console.WriteLine( string.Format("I got you {0}, {1} is the best.",this.sponsor.Name, this.name));
}
}
class JavaScript : ProgramLanguage
{
public JavaScript(string name, Sponsor sponsor)
: base(name, sponsor)
{
sponsor.programLs += this.Speak;
}
public override void Speak()
{
Console.WriteLine(string.Format("I got you {0}, {1} is the best.", this.sponsor.Name, this.name));
}
}
class C : ProgramLanguage
{
public C(string name, Sponsor sponsor)
: base(name, sponsor)
{
sponsor.programLs += this.Speak;
}
public override void Speak()
{
Console.WriteLine(string.Format("I got you {0}, {1} is the best.", this.sponsor.Name, this.name));
}
}
class CSharp : ProgramLanguage
{
public CSharp(string name, Sponsor sponsor)
: base(name, sponsor)
{
sponsor.programLs += this.Speak;
}
public override void Speak()
{
Console.WriteLine(string.Format("I got you {0}, {1} is the best.", this.sponsor.Name, this.name));
}
}
/// <summary>
/// 客户端调用
/// </summary>
static void Main(string[] args)
{
Sponsor pc = new Sponsor("PC");
Java jv = new Java("java", pc); // 每实例化一个对象,事件处理程序(speak)就被注册到事件中
JavaScript js = new JavaScript("javascript", pc);
pc.BeginSpeak(); // pc通知一组程序语言发言
pc.EndSpeak(); // pc最后通知发言结束
Sponsor mac = new Sponsor("MAC");
C c = new C("c", mac);
CSharp cs = new CSharp("c#", mac);
mac.BeginSpeak();// mac通知一组程序语言发言
mac.EndSpeak(); // mac最后通知发言结束
Console.Read();
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace CsStudy
{
class EventStudy
{
/// <summary>
/// 主办方 *** 发送器,被观察对象,他负责发送消息通知参会者发言
/// </summary>
public class Sponsor
{
public delegate void LanguageSpeak(); //声明委托
public event LanguageSpeak programLs; //定义事件,当主办方“通知”发言时,触发它
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
public Sponsor(string name)
{
this.name = name;
}
public void BeginSpeak()
{
Console.WriteLine(string.Format("I'm one of the sponsors,my name is {0}.Ok,here we go.", this.name));
if (programLs != null)
{
programLs();
}
}
public void EndSpeak()
{
Console.WriteLine(string.Format("I'm {0},thank you for your excellent report.", this.name));
}
}
/// <summary>
/// 编程语言抽象类
/// </summary>
abstract class ProgramLanguage
{
public Sponsor sponsor;
public string name;
public ProgramLanguage(string name,Sponsor sponsor)
{
this.name = name;
this.sponsor = sponsor;
}
public abstract void Speak();
}
/* 被邀请发言的编程语言包括java,javascript,c,c# , 接收器,主办方一有“通知”,他们就发言*/
class Java : ProgramLanguage
{
public Java(string name,Sponsor sponsor)
: base(name,sponsor)
{
sponsor.programLs += this.Speak; //在构造函数里注册事件处理程序
}
public override void Speak()
{
Console.WriteLine( string.Format("I got you {0}, {1} is the best.",this.sponsor.Name, this.name));
}
}
class JavaScript : ProgramLanguage
{
public JavaScript(string name, Sponsor sponsor)
: base(name, sponsor)
{
sponsor.programLs += this.Speak;
}
public override void Speak()
{
Console.WriteLine(string.Format("I got you {0}, {1} is the best.", this.sponsor.Name, this.name));
}
}
class C : ProgramLanguage
{
public C(string name, Sponsor sponsor)
: base(name, sponsor)
{
sponsor.programLs += this.Speak;
}
public override void Speak()
{
Console.WriteLine(string.Format("I got you {0}, {1} is the best.", this.sponsor.Name, this.name));
}
}
class CSharp : ProgramLanguage
{
public CSharp(string name, Sponsor sponsor)
: base(name, sponsor)
{
sponsor.programLs += this.Speak;
}
public override void Speak()
{
Console.WriteLine(string.Format("I got you {0}, {1} is the best.", this.sponsor.Name, this.name));
}
}
/// <summary>
/// 客户端调用
/// </summary>
static void Main(string[] args)
{
Sponsor pc = new Sponsor("PC");
Java jv = new Java("java", pc); // 每实例化一个对象,事件处理程序(speak)就被注册到事件中
JavaScript js = new JavaScript("javascript", pc);
pc.BeginSpeak(); // pc通知一组程序语言发言
pc.EndSpeak(); // pc最后通知发言结束
Sponsor mac = new Sponsor("MAC");
C c = new C("c", mac);
CSharp cs = new CSharp("c#", mac);
mac.BeginSpeak();// mac通知一组程序语言发言
mac.EndSpeak(); // mac最后通知发言结束
Console.Read();
}
}
}
从上面的代码中,我们可以看清楚事件的工作流程:发送器定义委托,声明事件;接收器注册事件处理程序(speak)到事件中去;发送器状态改变发出“通知”时,事件触发,注册事件的各个接收器及时“获取”消息,处理相应程序,如发言(speak)。如果我们在Java类的构造函数中注释掉”sponsor.programLs += this.Speak;“这一行,那么这个接收器(java)也就不会收到通知,并发言(speak)了。
我们经常在c#程序中看到如:
protected void Page_Load(object sender, EventArgs e)
{
}
这样的事件形式。最后,我们来改造之前的代码,也模仿一下ms的优雅的写法:
Code
using System;
using System.Collections.Generic;
using System.Text;
namespace CsStudy
{
class EventStudy
{
/// <summary>
/// EventArgs是包含事件数据的类的基类,它是在事件触发时,传递数据用的
/// </summary>
public class BeginSpeakEventArgs : EventArgs
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
/// <summary>
/// 主办方 *** 发送器,被观察对象,他负责发送消息通知参会者发言
/// </summary>
public class Sponsor
{
public delegate void LanguageSpeak(object sender,BeginSpeakEventArgs args); //声明委托
public event LanguageSpeak programLs; //定义事件,当主办方“通知”发言时,触发它
private string name;
public Sponsor(string name)
{
this.name = name;
}
public void BeginSpeak()
{
Console.WriteLine(string.Format("I'm one of the sponsors,my name is {0}.Ok,here we go.", this.name));
if (programLs != null)
{
BeginSpeakEventArgs e=new BeginSpeakEventArgs();
e.Name=this.name; // 将当前主办方名告知事件数据类,这样接受者就可以根据事件数据类来获知是哪一个主办方在通知发言
programLs(this,e);
}
}
public void EndSpeak()
{
Console.WriteLine(string.Format("I'm {0},thank you for your excellent report.", this.name));
}
}
/// <summary>
/// 编程语言抽象类
/// </summary>
abstract class ProgramLanguage
{
public Sponsor sponsor;
public string name;
public ProgramLanguage(string name,Sponsor sponsor)
{
this.name = name;
this.sponsor = sponsor;
}
public abstract void Speak(object sender,BeginSpeakEventArgs args);
}
/* 被邀请发言的编程语言包括java,javascript,c,c# , 接收器,主办方一有“通知”,他们就发言*/
class Java : ProgramLanguage
{
public Java(string name, Sponsor sponsor)
: base(name, sponsor)
{
sponsor.programLs += this.Speak; //在构造函数里注册事件处理程序
}
public override void Speak(object sender, BeginSpeakEventArgs args) // 接受者就可以根据事件数据类args.Name来获知是哪一个主办方在通知发言
{
Console.WriteLine(string.Format("I got you {0}, {1} is the best.", args.Name, this.name));
}
}
class JavaScript : ProgramLanguage
{
public JavaScript(string name, Sponsor sponsor)
: base(name, sponsor)
{
sponsor.programLs += this.Speak;
}
public override void Speak(object sender, BeginSpeakEventArgs args)
{
Console.WriteLine(string.Format("I got you {0}, {1} is the best.", args.Name, this.name));
}
}
class C : ProgramLanguage
{
public C(string name, Sponsor sponsor)
: base(name, sponsor)
{
sponsor.programLs += this.Speak;
}
public override void Speak(object sender, BeginSpeakEventArgs args)
{
Console.WriteLine(string.Format("I got you {0}, {1} is the best.", args.Name, this.name));
}
}
class CSharp : ProgramLanguage
{
public CSharp(string name, Sponsor sponsor)
: base(name, sponsor)
{
sponsor.programLs += this.Speak;
}
public override void Speak(object sender, BeginSpeakEventArgs args)
{
Console.WriteLine(string.Format("I got you {0}, {1} is the best.", args.Name, this.name));
}
}
/// <summary>
/// 客户端调用
/// </summary>
static void Main(string[] args)
{
Sponsor pc = new Sponsor("PC");
Java jv = new Java("java", pc); // 每实例化一个对象,事件处理程序(speak)就被注册到事件中
JavaScript js = new JavaScript("javascript", pc);
pc.BeginSpeak(); // pc通知一组程序语言发言
pc.EndSpeak(); // pc最后通知发言结束
Sponsor mac = new Sponsor("MAC");
C c = new C("c", mac);
CSharp cs = new CSharp("c#", mac);
mac.BeginSpeak();// mac通知一组程序语言发言
mac.EndSpeak(); // mac最后通知发言结束
Console.Read();
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace CsStudy
{
class EventStudy
{
/// <summary>
/// EventArgs是包含事件数据的类的基类,它是在事件触发时,传递数据用的
/// </summary>
public class BeginSpeakEventArgs : EventArgs
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
/// <summary>
/// 主办方 *** 发送器,被观察对象,他负责发送消息通知参会者发言
/// </summary>
public class Sponsor
{
public delegate void LanguageSpeak(object sender,BeginSpeakEventArgs args); //声明委托
public event LanguageSpeak programLs; //定义事件,当主办方“通知”发言时,触发它
private string name;
public Sponsor(string name)
{
this.name = name;
}
public void BeginSpeak()
{
Console.WriteLine(string.Format("I'm one of the sponsors,my name is {0}.Ok,here we go.", this.name));
if (programLs != null)
{
BeginSpeakEventArgs e=new BeginSpeakEventArgs();
e.Name=this.name; // 将当前主办方名告知事件数据类,这样接受者就可以根据事件数据类来获知是哪一个主办方在通知发言
programLs(this,e);
}
}
public void EndSpeak()
{
Console.WriteLine(string.Format("I'm {0},thank you for your excellent report.", this.name));
}
}
/// <summary>
/// 编程语言抽象类
/// </summary>
abstract class ProgramLanguage
{
public Sponsor sponsor;
public string name;
public ProgramLanguage(string name,Sponsor sponsor)
{
this.name = name;
this.sponsor = sponsor;
}
public abstract void Speak(object sender,BeginSpeakEventArgs args);
}
/* 被邀请发言的编程语言包括java,javascript,c,c# , 接收器,主办方一有“通知”,他们就发言*/
class Java : ProgramLanguage
{
public Java(string name, Sponsor sponsor)
: base(name, sponsor)
{
sponsor.programLs += this.Speak; //在构造函数里注册事件处理程序
}
public override void Speak(object sender, BeginSpeakEventArgs args) // 接受者就可以根据事件数据类args.Name来获知是哪一个主办方在通知发言
{
Console.WriteLine(string.Format("I got you {0}, {1} is the best.", args.Name, this.name));
}
}
class JavaScript : ProgramLanguage
{
public JavaScript(string name, Sponsor sponsor)
: base(name, sponsor)
{
sponsor.programLs += this.Speak;
}
public override void Speak(object sender, BeginSpeakEventArgs args)
{
Console.WriteLine(string.Format("I got you {0}, {1} is the best.", args.Name, this.name));
}
}
class C : ProgramLanguage
{
public C(string name, Sponsor sponsor)
: base(name, sponsor)
{
sponsor.programLs += this.Speak;
}
public override void Speak(object sender, BeginSpeakEventArgs args)
{
Console.WriteLine(string.Format("I got you {0}, {1} is the best.", args.Name, this.name));
}
}
class CSharp : ProgramLanguage
{
public CSharp(string name, Sponsor sponsor)
: base(name, sponsor)
{
sponsor.programLs += this.Speak;
}
public override void Speak(object sender, BeginSpeakEventArgs args)
{
Console.WriteLine(string.Format("I got you {0}, {1} is the best.", args.Name, this.name));
}
}
/// <summary>
/// 客户端调用
/// </summary>
static void Main(string[] args)
{
Sponsor pc = new Sponsor("PC");
Java jv = new Java("java", pc); // 每实例化一个对象,事件处理程序(speak)就被注册到事件中
JavaScript js = new JavaScript("javascript", pc);
pc.BeginSpeak(); // pc通知一组程序语言发言
pc.EndSpeak(); // pc最后通知发言结束
Sponsor mac = new Sponsor("MAC");
C c = new C("c", mac);
CSharp cs = new CSharp("c#", mac);
mac.BeginSpeak();// mac通知一组程序语言发言
mac.EndSpeak(); // mac最后通知发言结束
Console.Read();
}
}
}
关于事件和委托,本篇和上一篇不过是按照自己的思路入门介绍一下,高手不值一哂。读者可以参考网上无数高明的文章。