從老李打漁淺析C#中的委托/事件機(jī)制(1)
這幾天在整理C#語言,發(fā)現(xiàn)還有很多東西由于沒有真正用到,理解得都很膚淺。比如:委托,感覺就是一個(gè)函數(shù)指針,用來實(shí)現(xiàn)事件模型。直到今天看到一篇老外的文章,感覺理解加深了不少。于是決定結(jié)合自己的理解重新寫一下,也算是總結(jié)吧。
緊耦合
從前,在東海邊有個(gè)村子,有個(gè)漁夫叫老李,世代以打漁為生。而村里的王員外是老李的老客戶,每天都要向老李買鮮魚。因?yàn)檫@個(gè)村子只有老李一個(gè)漁夫,所以老李的生意非常紅火,以至于王員外要想買到新鮮的魚就一定要盯緊老李,否則就只能買到小魚了。“老李,你隨時(shí)給我電話,匯報(bào)打漁情況,我要買到最好的魚,最新鮮的魚,錢不是問題!”。于是就有了下面一幕:
FishMan.cs
using System;
namespace delegateMain
{
///
/// FishMan 的摘要說明。
///
public class FishMan
{
private Wang _wang;
public FishMan()
{
//
// TODO: 在此處添加構(gòu)造函數(shù)邏輯
//
}
public void Advise(Wang wang) { _wang = wang; }
public void DoWork()
{
Console.WriteLine("漁夫老李: 王員外,我開始下網(wǎng)");
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: 在此處添加構(gòu)造函數(shù)邏輯
//
}
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
{
///
/// 應(yīng)用程序的主入口點(diǎn)。
///
[STAThread]
static void Main(string[] args)
{
FishMan li = new FishMan();
Wang WangYuanWai = new Wang();
li.Advise(WangYuanWai);
li.DoWork();
Console.WriteLine("Main: 打魚完成");
Console.ReadLine();
}
}
}
![]()
接口
后來張財(cái)主也要搶著買老李的魚,而且也要老李及時(shí)向他反饋打漁的情況,于是老李覺得有必要搞個(gè)售前服務(wù)部對(duì)這些個(gè)財(cái)主員外們反饋信息。
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("張財(cái)主:打吧。(還沒打漁就打電話啊)"); }
public void WorkProgressing() { Console.WriteLine("張財(cái)主:打到魚了再告訴我,煩不煩"); }
public int WorkCompleted()
{
Console.WriteLine("張財(cái)主:老李你的魚打上來多少,我要十斤?");
return 20; /* 總分為10 */
}
}
}
FishMan.cs
using System;
namespace delegateMain
{
///
/// FishMan 的摘要說明。
///
public class FishMan
{
private IWorkerEvents _events;
public FishMan()
{
//
// TODO: 在此處添加構(gòu)造函數(shù)邏輯
//
}
public void Advise(IWorkerEvents events) { _events = events; }
public void DoWork()
{
Console.WriteLine("漁夫老李: 尊敬的客戶,我開始下網(wǎng)");
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
{
///
/// 應(yīng)用程序的主入口點(diǎn)。
///
[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();
}
}
}

![]()

浙公網(wǎng)安備 33010602011771號(hào)