委托时一种特殊的类型,它用来保存方法的地址,这样咱们很方便的调用方法,像变量同样传递,回调。数组
C++中的函数指针也是保存方法的地址,可是有一点不同的是定义委托的时候就知道了它里面能够保存什么样的方法,而函数指针就没有这些安全
因此委托相对更明确一点,更安全一点。函数
public delegate void MyDelegate(int x) //这样的委托类型表示,该委托能够用来保存无返回值,切参数为int类型的方法
固然当咱们写出上面那段代码的时候,实际上编译器作了其余一些事,实际可能定义像下面这样的spa
public class MyDelegate:system.MusticastDelegate { public MyDelegate(object obj,IntPtr method){……} //obj保存,方法的实例(静态方法则null),IntPtr保存方法地址 public virtual void Invoke(int value){……} //调用方法 ……//省略 }
MusticastDelegate 内部有指针
_target字段 //保存当前委托保存方法,要使用的实例code
_methodPtr字段 //保存委托保存的方法对象
_invoalcationList字段 //保存委托链(若是只有一个委托就Null)blog
public class MyClass{ Public void Method1(int y){ } public static void Method2(int y){ } }
一、当咱们使用MyDelegate del = new MyDelegate(new MyClass().Method1);get
那么del对象中_target则保存了new MyClass()实例编译器
_methodPtr保存了Method1地址
_invoalcationList此时为NULL,由于只有一个委托
当咱们调用del(10),其实是调用del.Invoke(10) 而后Invoke执行的是_target._methodPtr(10)
二、当咱们使用MyDelegate del2 = new MyDelegate(MyClass.Method2);
那么del2对象中_target则保存了NULL,由于是保存静态方法,因此没有对象
_methodPtr保存了Method2地址
_invoalcationList此时为NULL,由于只有一个委托
当咱们调用del2(10),其实是调用del2.Invoke(10) 而后Invoke执行的是_target._methodPtr(10) 由于_target是null,因此实际是MyClass._methodPtr
三、del+=del2
那么实际是执行了del = Delegate.Combine(del,del2)
内部是建立了_invoalcationList数组,里面包含有两个委托del,del2
_target =null
_methodPtr =Method2地址
当咱们调用del(10)时发现_invoalcationList里面有两个委托,则循环这个数组,分别调用每一个委托