程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#基礎知識 >> .NET委托:一個關於C#的睡前故事

.NET委托:一個關於C#的睡前故事

編輯:C#基礎知識
  緊耦合

  從前,在南方一塊奇異的土地上,有個工人名叫彼得,他非常勤奮,對他的老板總是百依百順。但是他的老板是個吝啬的人,從不信任別人,堅決要求隨時知道彼得的工作進度,以防止他偷懶。但是彼得又不想讓老板呆在他的辦公室裡站在背後盯著他,於是就對老板做出承諾:無論何時,只要我的工作取得了一點進展我都會及時讓你知道。彼得通過周期性地使用“帶類型的引用”(原文為:“typed reference” 也就是delegate??)“回調”他的老板來實現他的承諾,如下:

class Worker {
 public void Advise(Boss boss) { _boss = boss; }
 public void DoWork() {
  Console.WriteLine(“工作: 工作開始”);
  if( _boss != null ) _boss.WorkStarted();
   Console.WriteLine(“工作: 工作進行中”);
  if( _boss != null ) _boss.WorkProgressing();

   Console.WriteLine("“工作: 工作完成”");
  if( _boss != null ) {
   int grade = _boss.WorkCompleted();
   Console.WriteLine(“工人的工作得分=” + grade);
  }
 }
 private Boss _boss;
}

class Boss {
 public void WorkStarted() { /* 老板不關心。 */ }
 public void WorkProgressing() { /*老板不關心。 */ }
 public int WorkCompleted() {
  Console.WriteLine(“時間差不多!”);
  return 2; /* 總分為10 */
 }
}

class Universe {
 static void Main() {
  Worker peter = new Worker();
  Boss boss = new Boss();
  peter.Advise(boss);
  peter.DoWork();

  Console.WriteLine(“Main: 工人工作完成”);
  Console.ReadLine();
 }
}
  接口

  現在,彼得成了一個特殊的人,他不但能容忍吝啬的老板,而且和他周圍的宇宙也有了密切的聯系,以至於他認為宇宙對他的工作進度也感興趣。不幸的是,他必須也給宇宙添加一個特殊的回調函數Advise來實現同時向他老板和宇宙報告工作進度。彼得想要把潛在的通知的列表和這些通知的實現方法分離開來,於是他決定把方法分離為一個接口:

interface IWorkerEvents {
 void WorkStarted();
 void WorkProgressing();
 int WorkCompleted();
}

class Worker {
 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);
  }
 }
 private IWorkerEvents _events;
}

class Boss : IWorkerEvents {
 public void WorkStarted() { /* 老板不關心。 */ }
 public void WorkProgressing() { /* 老板不關心。 */ }
 public int WorkCompleted() {
  Console.WriteLine(“時間差不多!”);
  return 3; /* 總分為10 */
 }
}
  委托

  不幸的是,每當彼得忙於通過接口的實現和老板交流時,就沒有機會及時通知宇宙了。至少他應該忽略身在遠方的老板的引用,好讓其他實現了IWorkerEvents的對象得到他的工作報告。

  他的老板還是抱怨得很厲害。“彼得!”他老板吼道,“你為什麼在工作一開始和工作進行中都來煩我?!我不關心這些事件。你不但強迫我實現了這些方法,而且還在浪費我寶貴的工作時間來處理你的事件,特別是當我外出的時候更是如此!你能不能不再來煩我?”

  於是,彼得意識到接口雖然在很多情況都很有用,但是當用作事件時,“粒度”不夠好。他希望能夠僅在別人想要時才通知他們,於是他決定把接口的方法分離為單獨的委托,每個委托都像一個小的接口方法:

delegate void WorkStarted();
delegate void WorkProgressing();
delegate int WorkCompleted();

class Worker {
 public void DoWork() {
  Console.WriteLine(“工作: 工作開始”);
  if( started != null ) started();

  Console.WriteLine(“工作: 工作進行中”);
  if( progressing != null ) progressing();

  Console.WriteLine("“工作: 工作完成”");
  if( completed != null ) {
   int grade = completed();
   Console.WriteLine(“工人的工作得分=” + grade);
  }
 }
 public WorkStarted started;
 public WorkProgressing progressing;
 public WorkCompleted completed;
}

class Boss {
 public int WorkCompleted() {
  Console.WriteLine("Better...");
  return 4; /* 總分為10 */
 }
}

class Universe {
 static void Main() {
  Worker peter = new Worker();
  Boss boss = new Boss();
  peter.completed = new WorkCompleted(boss.WorkCompleted);
  peter.DoWork();

  Console.WriteLine(“Main: 工人工作完成”);
  Console.ReadLine();
 }
}
  • 首頁
  • 上一頁
  • 1
  • 2
  • 3
  • 下一頁
  • 尾頁
  • 共3頁
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved