Delegate 類簡介

Delegate類簡介
------------------------     
命名空間:System
程序集:mscorlib(在 mscorlib.dll 中)

   委託(Delegate)類是一種數據結構,通過它可引用靜態方法或引用類實例及該類的實例方法。
以往的界面編程中我們應該都接觸過各種類型的事件驅動(event driven)的處理模式,
在這種模式裏,我們定義相應事件觸發的函數。
例如:
Button1 的 Click事件,我們可以編寫Button1_Click 或 Btn1Clicked等函數來做相應的驅動處理。
而事件與驅動函數的對應關係就是通過委託(Delegate)類來關聯的。

其實委託(Delegate)類這種數據結構有些類似於之前C/C++中的函數指針

Delegate類一個簡單應用
------------------------    
1.定義一個Delegate函數數據結構
2.定義Delegate將引用的靜態方法或引用類實例及該類的實例方法
3.Delegate數據變量指向實例方法
4.通過Delegate數據變量執行實例方法

A very basic example (TestClass.cs):

using System;

namespace MySample
{
    class TestClass
    {
    //1.定義一個Delegate函數數據結構
        public delegate void GoDelegate();

        [STAThread]
        static void Main(string[] args)
        {
        //3.Delegate數據變量指向實例方法
            GoDelegate goDelegate = new GoDelegate( MyDelegateFunc);

        //4.通過Delegate數據變量執行實例方法
            goDelegate();
            return;
        }
  
        //2.定義Delegate將引用的靜態方法或引用類實例及該類的實例方法
        public static void MyDelegateFunc()
        {
            Console.WriteLine("delegate function...");
        }       
    }
}

編譯執行結果:

# TestClass.exe
delegate function...

使用Delegate類和Override實現多態的比較
-----------------------------------------------
1.使用Delegate類的時候,下面的例子可以很清楚的說明。
  1.1 首先定義一個動物基類(MyAnimalDelegateClass), 基類中有顯示屬性的(ShowAnimalType)的public方法。
      並且在ShowAnimalType方法中調用Delegate引用的實例方法

  1.2 定義獅子(LionDelegateClass)和馬(HorseDelegateClass)兩個子類。Delegate與各自的實例方法綁定
      實現不同的屬性顯示(ShowAnimalType)方法。

////Delegate example (TestClass.cs):

using System;

namespace MySample
{
   class TestClass
   {
      [STAThread]
      static void Main(string[] args)
      {
      //獅子(LionDelegateClass)的屬性顯示(ShowAnimalType)方法調用
         LionDelegateClass lionDelegate = new LionDelegateClass();
         lionDelegate.ShowAnimalType("MySample");

      //馬(HorseDelegateClass)的屬性顯示(ShowAnimalType)方法調用
         HorseDelegateClass horseDelegate = new HorseDelegateClass();
         horseDelegate.ShowAnimalType("MySample");
      }
   }

   //動物基類(MyAnimalDelegateClass)
   public class MyAnimalDelegateClass
   {
      //Delegate數據結構定義
      public delegate void DelegateFunction(string strFuncName);

      private DelegateFunction m_delegateFunction = null;

      //Delegate類型的屬性
      public DelegateFunction delegateFunction
      {
         get
         {
            return m_delegateFunction;
         }
         set
         {
            m_delegateFunction = value;
         }
      }
   
      //屬性顯示(ShowAnimalType)方法
      public void ShowAnimalType(string strFuncName)
      {
         if (delegateFunction != null)
         {
            object[] args = {strFuncName};
         //調用Delegate引用的實例方法
            delegateFunction.DynamicInvoke(args);
         }
      }
   }

   //獅子(LionDelegateClass)
   public class LionDelegateClass:MyAnimalDelegateClass
   {
      public LionDelegateClass()
      {
         this.delegateFunction = new DelegateFunction(subFunction1);
      }

      //獅子(LionDelegateClass)實例方法的實裝
      private void subFunction1(string strFuncName)
      {
         System.Console.WriteLine(
            string.Format("[{0}]This is a lion....", strFuncName));
      }
   }

   //馬(HorseDelegateClass)
   public class HorseDelegateClass:MyAnimalDelegateClass
   {
      public HorseDelegateClass()
      {
         this.delegateFunction = new DelegateFunction(subFunction2);
      }

      //馬(HorseDelegateClass)實例方法的實裝
      private void subFunction2(string strFuncName)
      {
         System.Console.WriteLine(
            string.Format("[{0}]This is a horse....", strFuncName));
      }
   }
}

編譯執行結果:

# TestClass.exe

[MySample]This is a lion....
[MySample]This is a horse....

2.使用Override實裝的時候,參考下面的例子。
  1.1 首先定義一個動物基類(AbstractAnimalNoDelegateClass), 基類中有顯示屬性的(ShowAnimalType)的public方法。
      並且在ShowAnimalType方法中調用抽象方法(NoDelegateFunction)

  1.2 定義獅子(LionNoDelegateClass)和馬(HorseNoDelegateClass)兩個子類。
      子類中實裝抽象方法(NoDelegateFunction)
      實現不同的屬性顯示(ShowAnimalType)方法。

////Override example (TestClass.cs):

using System;

namespace MySample
{
   class TestClass
   {
      [STAThread]
      static void Main(string[] args)
      {
          //獅子(LionNoDelegateClass )的屬性顯示(ShowAnimalType)方法調用
          LionNoDelegateClass lionNoDelegate = new LionNoDelegateClass();
       lionNoDelegate.ShowAnimalType("MySample");

          //馬(HorseNoDelegateClass )的屬性顯示(ShowAnimalType)方法調用
       HorseNoDelegateClass horseNoDelegate = new HorseNoDelegateClass();
       horseNoDelegate.ShowAnimalType("MySample");
      }
   }

   //動物基類(AbstractAnimalNoDelegateClass)
    public abstract class AbstractAnimalNoDelegateClass
    {
        public void ShowAnimalType(string strFuncName)
        {
            //抽象方法(NoDelegateFunction)調用
            NoDelegateFunction(strFuncName);
        }
        //在基類中定義抽象方法(NoDelegateFunction)
        protected abstract void NoDelegateFunction(string strFuncName);
    }

    //獅子(LionNoDelegateClass )
    public class LionNoDelegateClass:AbstractAnimalNoDelegateClass
    {
    // 子類中實裝抽象方法(NoDelegateFunction)
        protected override void NoDelegateFunction(string strFuncName)
        {
            System.Console.WriteLine(
                string.Format("[{0}]This is a lion....", strFuncName));
        }
    }
   
   //馬(HorseNoDelegateClass )
    public class HorseNoDelegateClass:AbstractAnimalNoDelegateClass
    {
    // 子類中實裝抽象方法(NoDelegateFunction)
        protected override void NoDelegateFunction(string strFuncName)
        {
            System.Console.WriteLine(
                string.Format("[{0}]This is a horse....", strFuncName));
        }
    }
}

編譯執行結果:

# TestClass.exe

[MySample]This is a lion....
[MySample]This is a horse....

3.比較Delegate和Override實裝方式
  可以看出Delegate實裝方式中,相當於定義一個函數指針成員變量
  通過把實裝函數的地址賦給該成員變量,實現同樣的方法,處理方式的不同。
  而Override方式中,則是在父類中預先定義好接口,通過實裝的不同,
  來實現同樣的方法,處理方式的不同。
  Delegate實裝方式比較靈活,適合設計不是很完善的場合,便於修改。
  Override方式封裝性好,相對比較安全。

MulticastDelegate 類的應用
---------------------------------
在C#中,委託(Delegate)類是多路委託,這就說可以同時指向多個處理函數,
並且可以按照委託的先後順序,執行相應的函數。
    
如下例:
using System;

namespace MySample
{
    class TestClass
    {
        [STAThread]
        static void Main(string[] args)
        {
            DogDelegateClass dogDelegate = new DogDelegateClass();
            dogDelegate.ShowAnimalType("MySample");

    }

    public class MyAnimalDelegateClass
    {
        public delegate void DelegateFunction(string strFuncName);

        private DelegateFunction m_delegateFunction = null;

        public DelegateFunction delegateFunction
        {
            get
            {
                return m_delegateFunction;
            }
            set
            {
                m_delegateFunction = value;
            }
        }

        public void ShowAnimalType(string strFuncName)
        {
            if (delegateFunction != null)
            {
                object[] args = {strFuncName};

                delegateFunction.DynamicInvoke(args);
            }
        }
    }

    public class DogDelegateClass:MyAnimalDelegateClass
    {
        public DogDelegateClass()
        {
      //多路委託函數 設定
            this.delegateFunction =  new DelegateFunction(subFunction31);
            this.delegateFunction += new DelegateFunction(subFunction32);
        }
  //委託函數1
        private void subFunction31(string strFuncName)
        {
            System.Console.WriteLine(
                string.Format("[{0}]This is a dog....", strFuncName));
        }
  //委託函數2
        private void subFunction32(string strFuncName)
        {
            System.Console.WriteLine(
                string.Format("[{0}]This is a nice dog....", strFuncName));
        }
    }
}

編譯執行結果:

# TestClass.exe

[MySample]This is a dog....
[MySample]This is a nice dog....
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章