1. 程式人生 > >C#中委托的理解

C#中委托的理解

and 耦合性 cli 用戶 tab handler table readline ole

  請註意,這只是個人關於C#中委托的一點點理解,參考了一些博客,如有不周之處,請指出,謝謝!

  委托是一種函數指針,委托是方法的抽象,方法是委托的實例。委托是C#語言的一道坎,明白了委托才能算是C#真正入了門。委托在c#中的應用特別的多,最常見比如事件監聽器就是利用委托來實現的。我們點擊winform上面的一個按鈕,系統就會響應,這其實就是委托。

  為什麽要用委托呢?絕對不是為了簡單問題復雜化。我們知道在程序設計當中,數據結構和算法是非常重要的,但是在實際的開發當中,我們好像又不太用的著這些東西,這是因為我們使用的都是高級語言,想java、c#這一類的。這些高級語言在設計的時候已經幫我們把這些問題考慮進去了,所以我們才感覺不到算法和數據結構的存在。舉個最簡單的例子,我們常用的List、HshTable之類的都是java幫我們定義好了的數據結構。委托也是這樣。委托的存在本質上是為了讓代碼解耦,實現代碼的可維護和可擴展。

  我們就以點擊一個按鈕,然後觸發一個事件為例來說明。

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響應"); } } }

C#中委托的理解