Delegate [重中之重] 委托
定义一:(参考)http://www.cnblogs.com/zhangchenliang/archive/2012/09/19/2694430.html
-
完全可以把delegate理解成C中的函数指针。 它允许你传递一个 类A 的 方法m 给另一个 类B 的对象,使得 类B 的对象能够调用这个 方法m ,说白了就是可以把方法当作参数传递。 不过delegate和函数指针还是有点区别的,delegate有许多函数指针不具备的优点。 首先:函数指针只能指向静态函数,而delegate既可以引用静态函数,又可以引用非静态成员函数。 在引用非静态成员函数时,delegate不但保存了对此函数入口指针的引用,而且还保存了调用此函数的类实例的引用。 其次,与函数指针相 比,delegate是面向对象、类型安全、可靠的受控(managed)对象。 也就是说,runtime能够保证delegate指向一个有效的方法, 你无须担心delegate会指向无效地址或者越界地址。
个人理解(利用原博主的源代码进行分析)
- 例一
1 namespace Jandar.Test.Yinxi{ 2 class DelegateTest{ 3 public delegate void CompareDelegate(int a,int b); 4 5 public static void Compare(int a,int b){ 6 System.Console.WriteLine((a>b).ToString()); 7 } 8 public static void Main(string[] args){ 9 CompareDelegate cd=new CompareDelegate(Compare); 10 cd(1,2); 11 12 //Compare(5,4);和上面两行的执行结果是一样的。 13 } 14 } 15 }
首先我们来分析一下 例一 的堆栈调用过程
1 CompareDelegate cd=new CompareDelegate(Compare);
因为 CompareDelegate 是一个引用类型。所以这步执行的是在 堆中创建一个引用类型对象
接下来执行 cd(1,2);
我以图解来描述一下
接下来的例二和上例一差不多 ,以下也给出源代码
-
1 namespace Jandar.Test.Yinxi 2 { 3 public delegate void MyTestDelegate(int i);//use like interface 4 5 public class DelegateTest 6 { 7 public static void Main() 8 { 9 RecieveDelegateArgsFuns(new MyTestDelegate(DelegateFunction)); 10 } 11 public static void RecieveDelegateArgsFuns(MyTestDelegate func) 12 { 13 func(21); 14 } 15 public static void DelegateFunction(int i) 16 { 17 System.Console.WriteLine("传来的参数{0}",i); 18 } 19 } 20 }
附上手稿
通过理解 .Net 中的OnClick 机制 来深入理解 Delegate
C#中的事件处理实际上是一种具有特殊签名的 delegate
public delegate void MyEventHandler(object sender, MyEventArgs e);
其中的两个参数,sender代表事件发送者,e是事件参数类。MyEventArgs类用来包含与事件相关的数据,所有的事件参数类都必须从 System.EventArgs类派生。当然,如果你的事件不含参数,那么可以直接用System.EventArgs类作为参数。(例子解释直接在代码中)
1 using System; 2 namespace Jandar.Test.YinXi 3 { 4 public class ButtonClickArgs : EventArgs 5 { 6 public string Clicker;//用来显示 操作对象。 7 } 8 public class MyButton 9 { 10 public delegate void ClickHandle(object sender, ButtonClickArgs e);//声明一个delegate的类型 11 12 public event ClickHandle OnClick;//定义事件,类型为 delegate 的ClickHandle对象; 13 public void Click() 14 { 15 OnClick(this, new ButtonClickArgs() { Clicker = "H" });////相当于 onClick中自带的 Invoke()方法,类似与 OnClick.Invoke( 16 //this, new ButtonClickArgs() { Clicker = "H" } 17 } 18 } 19 public class Program 20 { 21 public static void Main(string[] args) 22 { 23 MyButton btn = new MyButton(); 24 btn.OnClick += new MyButton.ClickHandle(btn_OnClick);//注册时间,把btn_OnClick 方法绑定到 委托事件中。 25 btn.Click();//进行调用 26 } 27 public static void btn_OnClick(object sender, ButtonClickArgs e) 28 { 29 Console.WriteLine("Hello,MyWorld!"); 30 } 31 } 32 }
定义二:(参考)http://www.cnblogs.com/idior/articles/100666.html
-
将Delegate理解为接口,只有一个方法的接口,这样最容易理解。这个方法只有声明,没有实现,实现在别的类。(实际上应该把它看作函数指针,不过接口更容易理解些。) 在你的类中有一个Delegate就相当于有一个接口。通过这个接口你可以调用一个方法,而这个方法在别的类定义,由别的类来干。
定义三:(参考)http://www.cnblogs.com/hyddd/archive/2009/07/26/1531538.html
-
Delegate中文翻译为“委托”。Msdn中对Delegate的解释如下: C#中的委托类似于C或C++中的函数指针。使用委托使程序员可以将方法引用封装在委托对象内。然后可以将该委托对象传递给可调用所引用方法的代码,
而不必在编译时知道将调用哪个方法。与C或C++中的函数指针不同,委托是面向对象、类型安全的,并且是安全的。
1 using System; 2 namespace Jandar.Test.YinXi{ 3 4 class TestDelegate 5 { 6 public delegate void DelegateMethod(); //声明了一个Delegate Type 7 8 public DelegateMethod delegateMethod; //声明了一个Delegate对象 9 10 public static void StaticMethod() 11 { 12 Console.WriteLine("Delegate a static method"); 13 } 14 15 public void NonStaticMethod() 16 { 17 Console.WriteLine("Delegate a non-static method"); 18 } 19 20 public void RunDelegateMethods() 21 { 22 if(delegateMethod != null){ 23 Console.WriteLine("---------"); 24 delegateMethod.Invoke(); //运行 delegateMethod所搭载的函数 25 Console.WriteLine("---------"); 26 } 27 } 28 } 29 30 class Program 31 { 32 static void OtherClassMethod(){ 33 Console.WriteLine("Delegate an other class's method"); 34 } 35 36 static void Main(string[] args) 37 { 38 var test = new TestDelegate(); 39 test.delegateMethod = new TestDelegate.DelegateMethod(test.NonStaticMethod); 40 test.delegateMethod += new TestDelegate.DelegateMethod(TestDelegate.StaticMethod); 41 test.delegateMethod += Program.OtherClassMethod; 42 test.RunDelegateMethods(); 43 } 44 } 45 }
上面这个例子我觉得挺好的,体现了定义一种的 解释
它允许你传递一个 类A 的 方法m 给另一个 类B 的对象,使得 类B 的对象能够调用这个 方法m ,说白了就是可以把方法当作参数传递。