从老李打渔浅析C#中的委托/事件机制(1)
这几天在整理C#语言,发现还有很多东西由于没有真正用到,理解得都很肤浅。比如:委托,感觉就是一个函数指针,用来实现事件模型。直到今天看到一篇老外的文章,感觉理解加深了不少。于是决定结合自己的理解重新写一下,也算是总结吧。
紧耦合
从前,在东海边有个村子,有个渔夫叫老李,世代以打渔为生。而村里的王员外是老李的老客户,每天都要向老李买鲜鱼。因为这个村子只有老李一个渔夫,所以老李的生意非常红火,以至于王员外要想买到新鲜的鱼就一定要盯紧老李,否则就只能买到小鱼了。“老李,你随时给我电话,汇报打渔情况,我要买到最好的鱼,最新鲜的鱼,钱不是问题!”。于是就有了下面一幕:
FishMan.cs
using System;
namespace delegateMain
{
///
/// FishMan 的摘要说明。
///
public class FishMan
{
private Wang _wang;
public FishMan()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public void Advise(Wang wang) { _wang = wang; }
public void DoWork()
{
Console.WriteLine("渔夫老李: 王员外,我开始下网");
if( _wang != null ) _wang.WorkStarted();
Console.WriteLine("渔夫老李: 王员外,我正在打鱼中");
if( _wang != null ) _wang.WorkProgressing();
Console.WriteLine("渔夫老李: 王员外,我鱼打上来了");
if( _wang != null )
{
int grade = _wang.WorkCompleted();
Console.WriteLine("渔夫老李:卖得银两=" + grade);
}
}
}
}
Wang.cs
using System;
namespace delegateMain
{
///
/// Wang 的摘要说明。
///
public class Wang
{
public Wang()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public void WorkStarted() {Console.WriteLine("王员外:好的。"); }
public void WorkProgressing() { Console.WriteLine("王员外:好的,好的。"); }
public int WorkCompleted()
{
Console.WriteLine("王员外:老李你的鱼打上来多少,多少一斤?");
return 2;
}
}
}
delegateMain.cs
using System;
namespace delegateMain
{
///
/// Class1 的摘要说明。
///
class FishManDemo
{
///
/// 应用程序的主入口点。
///
[STAThread]
static void Main(string[] args)
{
FishMan li = new FishMan();
Wang WangYuanWai = new Wang();
li.Advise(WangYuanWai);
li.DoWork();
Console.WriteLine("Main: 打鱼完成");
Console.ReadLine();
}
}
}
接口
后来张财主也要抢着买老李的鱼,而且也要老李及时向他反馈打渔的情况,于是老李觉得有必要搞个售前服务部对这些个财主员外们反馈信息。
IWorkerEvents.cs
using System;
namespace delegateMain
{
///
/// IWorkerEvents 的摘要说明。
///
public interface IWorkerEvents
{
void WorkStarted();
void WorkProgressing();
int WorkCompleted();
}
}
Wang.cs
using System;
namespace delegateMain
{
///
/// Wang 的摘要说明。
///
public class Wang : IWorkerEvents
{
public void WorkStarted() {Console.WriteLine("王员外:好的。"); }
public void WorkProgressing() { Console.WriteLine("王员外:好的,好的。"); }
public int WorkCompleted()
{
Console.WriteLine("王员外:老李你的鱼打上来多少,多少一斤?");
return 2;
}
}
}
Zhang.cs
using System;
namespace delegateMain
{
///
/// Zhang 的摘要说明。
///
public class Zhang : IWorkerEvents
{
public void WorkStarted() {Console.WriteLine("张财主:打吧。(还没打渔就打电话啊)"); }
public void WorkProgressing() { Console.WriteLine("张财主:打到鱼了再告诉我,烦不烦"); }
public int WorkCompleted()
{
Console.WriteLine("张财主:老李你的鱼打上来多少,我要十斤?");
return 20; /* 总分为10 */
}
}
}
FishMan.cs
using System;
namespace delegateMain
{
///
/// FishMan 的摘要说明。
///
public class FishMan
{
private IWorkerEvents _events;
public FishMan()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
public void Advise(IWorkerEvents events) { _events = events; }
public void DoWork()
{
Console.WriteLine("渔夫老李: 尊敬的客户,我开始下网");
if( _events != null ) _events.WorkStarted();
Console.WriteLine("渔夫老李: 尊敬的客户,我正在打鱼中");
if( _events != null ) _events.WorkProgressing();
Console.WriteLine("渔夫老李: 尊敬的客户,我鱼打上来了");
if( _events != null )
{
int grade = _events.WorkCompleted();
Console.WriteLine("渔夫老李:卖得银两=" + grade);
}
}
}
}
delegateMain.cs
using System;
namespace delegateMain
{
///
/// Class1 的摘要说明。
///
class FishManDemo
{
///
/// 应用程序的主入口点。
///
[STAThread]
static void Main(string[] args)
{
FishMan li = new FishMan();
IWorkerEvents WangYuanWai = new Wang();
IWorkerEvents Zhangcaizhu = new Zhang();
li.Advise(Zhangcaizhu);
li.DoWork();
Console.WriteLine("Main: 打鱼完成");
Console.ReadLine();
}
}
}