C#中委託的理解

  請注意,這只是我的關於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響應");
        }
    }

}
相關文章
相關標籤/搜索