现在的位置: 首页 > 综合 > 正文

C#中的delegate

2013年05月02日 ⁄ 综合 ⁄ 共 5871字 ⁄ 字号 评论关闭

转自:http://zhidao.baidu.com/link?url=xyEmK-9RCxUFgUPWbwTDp9kg3cdb-JRCG2V2oTTiPdHIZNI3BihhyGT_94ewNcz5PCvla_l6nsNyk8E5XoRa2a

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....

抱歉!评论已关闭.