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):
1: using System;
2:3: namespace MySample
4: {5: class TestClass
6: {7: //1.定义一个Delegate函数数据结构
8: public delegate void GoDelegate();9:10: [STAThread]11: static void Main(string[] args)12: {13: //3.Delegate数据变量指向实例方法
14: GoDelegate goDelegate = new GoDelegate( MyDelegateFunc);
15:16: //4.通过Delegate数据变量执行实例方法
17: goDelegate();18: return;
19: }20: //2.定义Delegate将引用的静态方法或引用类实例及该类的实例方法
21: public static void MyDelegateFunc()22: {23: Console.WriteLine("delegate function...");
24: }25: }26: }
编译执行结果:
# 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):
1: AnonymousDelegatesusing System;2:3: namespace MySample
4: {5: class TestClass
6: {7: [STAThread]8: static void Main(string[] args)9: {10: //狮子(LionDelegateClass)的属性显示(ShowAnimalType)方法调用
11: LionDelegateClass lionDelegate = new LionDelegateClass();
12: lionDelegate.ShowAnimalType("MySample");
13:14: //马(HorseDelegateClass)的属性显示(ShowAnimalType)方法调用
15: HorseDelegateClass horseDelegate = new HorseDelegateClass();
16: horseDelegate.ShowAnimalType("MySample");
17: }18: }19:20: //动物基类(MyAnimalDelegateClass)
21: public class MyAnimalDelegateClass22: {23: //Delegate数据结构定义
24: public delegate void DelegateFunction(string strFuncName);25:26: private DelegateFunction m_delegateFunction = null;27:28: //Delegate类型的属性
29: public DelegateFunction delegateFunction
30: {31: get
32: {33: return m_delegateFunction;
34: }35: set
36: {37: m_delegateFunction = value;
38: }39: }40: //属性显示(ShowAnimalType)方法
41: public void ShowAnimalType(string strFuncName)42: {43: if (delegateFunction != null)44: {45: object[] args = {strFuncName};
46: //调用Delegate引用的实例方法
47: delegateFunction.DynamicInvoke(args);48: }49: }50: }51:52: //狮子(LionDelegateClass)
53: public class LionDelegateClass:MyAnimalDelegateClass54: {55: public LionDelegateClass()
56: {57: this.delegateFunction = new DelegateFunction(subFunction1);58: }59:60: //狮子(LionDelegateClass)实例方法的实装
61: private void subFunction1(string strFuncName)62: {63: System.Console.WriteLine(64: string.Format("[{0}]This is a lion....", strFuncName));65: }66: }67:68: //马(HorseDelegateClass)
69: public class HorseDelegateClass:MyAnimalDelegateClass70: {71: public HorseDelegateClass()
72: {73: this.delegateFunction = new DelegateFunction(subFunction2);74: }75:76: //马(HorseDelegateClass)实例方法的实装
77: private void subFunction2(string strFuncName)78: {79: System.Console.WriteLine(80: string.Format("[{0}]This is a horse....", strFuncName));81: }82: }83: }
编译执行结果:
# 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):
1: using System;
2:3: namespace MySample
4: {5: class TestClass
6: {7: [STAThread]8: static void Main(string[] args)9: {10: //狮子(LionNoDelegateClass )的属性显示(ShowAnimalType)方法调用
11: LionNoDelegateClass lionNoDelegate = new LionNoDelegateClass();
12: lionNoDelegate.ShowAnimalType("MySample");
13:14: //马(HorseNoDelegateClass )的属性显示(ShowAnimalType)方法调用
15: HorseNoDelegateClass horseNoDelegate = new HorseNoDelegateClass();
16: horseNoDelegate.ShowAnimalType("MySample");
17: }18: }19:20: //动物基类(AbstractAnimalNoDelegateClass)
21: public abstract class AbstractAnimalNoDelegateClass22: {23: public void ShowAnimalType(string strFuncName)24: {25: //抽象方法(NoDelegateFunction)调用
26: NoDelegateFunction(strFuncName);27: }28: //在基类中定义抽象方法(NoDelegateFunction)
29: protected abstract void NoDelegateFunction(string strFuncName);30: }31:32: //狮子(LionNoDelegateClass )
33: public class LionNoDelegateClass:AbstractAnimalNoDelegateClass34: {35: // 子类中实装抽象方法(NoDelegateFunction)
36: protected override void NoDelegateFunction(string strFuncName)37: {38: System.Console.WriteLine(39: string.Format("[{0}]This is a lion....", strFuncName));40: }41: }42: //马(HorseNoDelegateClass )
43: public class HorseNoDelegateClass:AbstractAnimalNoDelegateClass44: {45: // 子类中实装抽象方法(NoDelegateFunction)
46: protected override void NoDelegateFunction(string strFuncName)47: {48: System.Console.WriteLine(49: string.Format("[{0}]This is a horse....", strFuncName));50: }51: }52: }53:
编译执行结果:
# TestClass.exe
[MySample]This is a lion....
[MySample]This is a horse....
3.比较Delegate和Override实装方式
可以看出Delegate实装方式中,相当于定义一个函数指针的成员变量。
通过把实装函数的地址赋给该成员变量,实现同样的方法,处理方式的不同。
而Override方式中,则是在父类中预先定义好接口,通过实装的不同,
来实现同样的方法,处理方式的不同。
Delegate实装方式比较灵活,适合设计不是很完善的场合,便于修改。
Override方式封装性好,相对比较安全。
MulticastDelegate 类的应用
---------------------------------
在C#中,委托(Delegate)类是多路委托,这就说可以同时指向多个处理函数,
并且可以按照委托的先后顺序,执行相应的函数。
如下例:
1: using System;
2:3: namespace MySample
4: {5: class TestClass
6: {7: [STAThread]8: static void Main(string[] args)9: {10: DogDelegateClass dogDelegate = new DogDelegateClass();
11: dogDelegate.ShowAnimalType("MySample");
12:13: }14:15: public class MyAnimalDelegateClass16: {17: public delegate void DelegateFunction(string strFuncName);18:19: private DelegateFunction m_delegateFunction = null;20:21: public DelegateFunction delegateFunction
22: {23: get
24: {25: return m_delegateFunction;
26: }27: set
28: {29: m_delegateFunction = value;
30: }31: }32:33: public void ShowAnimalType(string strFuncName)34: {35: if (delegateFunction != null)36: {37: object[] args = {strFuncName};
38:39: delegateFunction.DynamicInvoke(args);40: }41: }42: }43:44: public class DogDelegateClass:MyAnimalDelegateClass45: {46: public DogDelegateClass()
47: {48: //多路委托函数 设定
49: this.delegateFunction = new DelegateFunction(subFunction31);50: this.delegateFunction += new DelegateFunction(subFunction32);51: }52: //委托函数1
53: private void subFunction31(string strFuncName)54: {55: System.Console.WriteLine(56: string.Format("[{0}]This is a dog....", strFuncName));57: }58: //委托函数2
59: private void subFunction32(string strFuncName)60: {61: System.Console.WriteLine(62: string.Format("[{0}]This is a nice dog....", strFuncName));63: }64: }65: }
编译执行结果: # TestClass.exe [MySample]
This is a dog....[MySample]This is a nice dog....
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xinsir/archive/2006/08/22/1106277.aspx
1: // Copyright © Microsoft Corporation. All Rights Reserved.
2: // This code released under the terms of the
3: // Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.)
4: //
5: //Copyright (C) Microsoft Corporation. All rights reserved.
6:7: using System;
8: using System.Collections.Generic;
9: using System.Text;
10:11: namespace AnonymousDelegate_Sample
12: {13:14: // Define the delegate method.
15: delegate decimal CalculateBonus(decimal sales);16:17: // Define an Employee type.
18: class Employee
19: {20: public string name;21: public decimal sales;22: public decimal bonus;23: public CalculateBonus calculation_algorithm;
24: }25:26: class Program
27: {28:29: // This class will define two delegates that perform a calculation.
30: // The first will be a named method, the second an anonymous delegate.
31:32: // This is the named method.
33: // It defines one possible implementation of the Bonus Calculation algorithm.
34:35: static decimal CalculateStandardBonus(decimal sales)36: {37: return sales / 10;
38: }39:40: static void Main(string[] args)41: {42:43: // A value used in the calculation of the bonus.
44: // Note: This local variable will become a "captured outer variable".
45: decimal multiplier = 2;
46:47: // This delegate is defined as a named method.
48: CalculateBonus standard_bonus = new CalculateBonus(CalculateStandardBonus);
49:50: // This delegate is anonymous - there is no named method.
51: // It defines an alternative bonus calculation algorithm.
52: CalculateBonus enhanced_bonus = delegate(decimal sales)53: { return multiplier * sales / 10; };
54:55: // Declare some Employee objects.
56: Employee[] staff = new Employee[5];
57:58: // Populate the array of Employees.
59: for (int i = 0; i < 5; i++)60: staff[i] = new Employee();
61:62: // Assign initial values to Employees.
63: staff[0].name = "Mr Apple";
64: staff[0].sales = 100;65: staff[0].calculation_algorithm = standard_bonus;66:67: staff[1].name = "Ms Banana";
68: staff[1].sales = 200;69: staff[1].calculation_algorithm = standard_bonus;70:71: staff[2].name = "Mr Cherry";
72: staff[2].sales = 300;73: staff[2].calculation_algorithm = standard_bonus;74:75: staff[3].name = "Mr Date";
76: staff[3].sales = 100;77: staff[3].calculation_algorithm = enhanced_bonus;78:79: staff[4].name = "Ms Elderberry";
80: staff[4].sales = 250;81: staff[4].calculation_algorithm = enhanced_bonus;82:83: // Calculate bonus for all Employees
84: foreach (Employee person in staff)85: PerformBonusCalculation(person);86:87: // Display the details of all Employees
88: foreach (Employee person in staff)89: DisplayPersonDetails(person);90:91:92: }93:94: public static void PerformBonusCalculation(Employee person)95: {96:97: // This method uses the delegate stored in the person object
98: // to perform the calculation.
99: // Note: This method knows about the multiplier local variable, even though
100: // that variable is outside the scope of this method.
101: // The multipler varaible is a "captured outer variable".
102: person.bonus = person.calculation_algorithm(person.sales);103: }104:105: public static void DisplayPersonDetails(Employee person)106: {107: Console.WriteLine(person.name);108: Console.WriteLine(person.bonus);109: Console.WriteLine("---------------");
110: Console.ReadLine();111: }112: }113: }