請注意,這只是我的關於C#中委託的一點點理解,參考了一些博客,若有不周之處,請指出,謝謝!java
委託是一種函數指針,委託是方法的抽象,方法是委託的實例。委託是C#語言的一道坎,明白了委託才能算是C#真正入了門。委託在c#中的應用特別的多,最多見好比事件監聽器就是利用委託來實現的。咱們點擊winform上面的一個按鈕,系統就會響應,這其實就是委託。算法
爲何要用委託呢?絕對不是爲了簡單問題複雜化。咱們知道在程序設計當中,數據結構和算法是很是重要的,可是在實際的開發當中,咱們好像又不太用的着這些東西,這是由於咱們使用的都是高級語言,想java、c#這一類的。這些高級語言在設計的時候已經幫咱們把這些問題考慮進去了,因此咱們才感受不到算法和數據結構的存在。舉個最簡單的例子,咱們經常使用的List、HshTable之類的都是java幫咱們定義好了的數據結構。委託也是這樣。委託的存在本質上是爲了讓代碼解耦,實現代碼的可維護和可擴展。c#
咱們就以點擊一個按鈕,而後觸發一個事件爲例來講明。數據結構
public void btnConfirmOnClick() { FunctionA(); FunctionB(); }
在上面的這段代碼中,當一個按鈕被點擊的時候,就會去主動地調用FunctionA();FunctionB();這兩個方法,這就完成了咱們的任務啊。可是,當用戶的需求發生見二連三的改變的時候,上面的代碼就會被頻繁的改動,好比說,要新增長一個FunctionC(),這樣一來,說明上面這段代碼距離工程實踐的要求還有必定的距離。按照23種設計原則的要求,當代碼的耦合性太大的時候,就要對代碼進行拆分,怎麼拆分呢?就是引入一個新的類C,當按鈕被點擊的時候,btnConfirmOnClick()這個方法去通知類C,C再去調用FunctionA();FunctionB();這些方法,這其實就是委託的設計思想。數據結構和算法
下面是一段委託的代碼。函數
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace DelegateTest { class Program { static void Main(string[] args) { A a = new A(); // 定義按鈕A B b = new B(a); // 定義響應事件B C c = new C(a); // 定義響應事件C // 按鈕A被單擊 a.Raise("單擊"); // 按鈕A被雙擊 //a.Raise("雙擊"); // 按鈕A被三連擊 //a.Fall(); Console.ReadLine(); // 因爲B和C訂閱了A的事件,因此無需任何代碼,B和C均會按照約定進行動做。 } } /// <summary> /// 按鈕A點擊委託 /// </summary> /// <param name="hand">點擊:單擊、雙擊</param> public delegate void RaiseEventHandler(string hand); /// <summary> /// 按鈕A被三連擊委託 /// </summary> public delegate void FallEventHandler(); /// <summary> /// 按鈕A /// </summary> public class A { /// <summary> /// 按鈕A點擊事件 /// </summary> public event RaiseEventHandler RaiseEvent; /// <summary> /// 按鈕A被三連擊事件 /// </summary> public event FallEventHandler FallEvent; /// <summary> /// 點擊 /// </summary> /// <param name="hand">手:單擊、雙擊</param> public void Raise(string hand) { Console.WriteLine("按鈕A{0}點擊", hand); // 調用點擊事件,傳入單擊或雙擊手做爲參數 if (RaiseEvent != null) { RaiseEvent(hand); } } /// <summary> /// 被三連擊 /// </summary> public void Fall() { Console.WriteLine("按鈕A被三連擊"); // 調用被三連擊事件 if (FallEvent != null) { FallEvent(); } } } /// <summary> /// 響應事件B /// </summary> public class B { A a; public B(A a) { this.a = a; a.RaiseEvent += new RaiseEventHandler(a_RaiseEvent); // 訂閱點擊事件 a.RaiseEvent += new RaiseEventHandler(a_RaiseEvent); // 訂閱點擊事件 a.FallEvent += new FallEventHandler(a_FallEvent); // 訂閱被三連擊事件 } /// <summary> /// 按鈕點擊時的動做 /// </summary> /// <param name="hand">若按鈕A被單擊,則B攻擊</param> void a_RaiseEvent(string hand) { if (hand.Equals("單擊")) { Attack(); } } /// <summary> /// 按鈕被三連擊時的動做 /// </summary> void a_FallEvent() { Attack(); } /// <summary> /// 攻擊 /// </summary> public void Attack() { Console.WriteLine("響應事件B響應"); } } /// <summary> /// 響應事件C /// </summary> public class C { A a; public C(A a) { this.a = a; a.RaiseEvent += new RaiseEventHandler(a_RaiseEvent); // 訂閱點擊事件 a.FallEvent += new FallEventHandler(a_FallEvent); // 訂閱被三連擊事件 } /// <summary> /// 按鈕點擊時的動做 /// </summary> /// <param name="hand">若按鈕A被雙擊,則攻擊</param> void a_RaiseEvent(string hand) { if (hand.Equals("雙擊")) { Attack(); } } /// <summary> /// 按鈕被三連擊時的動做 /// </summary> void a_FallEvent() { Attack(); } /// <summary> /// 攻擊 /// </summary> public void Attack() { Console.WriteLine("響應事件C響應"); } } }