委托内部
当声明一个委托,如下:
delegate void Feedback(int value);
编译器实际上定义了如下一个类:
//所有创建的委托都继承自 MulticastDelegate 类 //而 MulticastDelegate 类继承自 Delegate class Feedback : MulticastDelegate { //从 MulticastDelegate 类继承的 Delegate 类继承而来 //当委托对象包装的是一个静态方法时,该字段存储的是null;包装的是实例方法时,存储的是回调方法要操作的对象的引用. object _target; //从 MulticastDelegate 类继承的 Delegate 类继承而来 //一个内部的整数值,CLR用它表示要回调的方法 //这个内部的整数值从 MethodDef 或者 MemberRef 元数据 token 获得 IntPtr _methodPtr; //从 MulticastDelegate 类继承而来 //该字段通常为null,当构造委托链时,它引用了一个委托数组 object _invocationList; //构造方法 public Feedback(object @object, IntPtr method) { this._target = @object; this._methodPtr = method; } //这个方法的参数,返回值和定义的委托的参数,返回值一模一样 public virtual void Invoke(int value) { ...} //下面两个方法实现对回调方法的异步回调 public virtual IAsyncResult BeginInvoke(int value,AsyncCallback callback,object @object) { ...} public virtual void EndInvoke(IAsyncResult result) { ...} }
//Invoke方法的伪代码: public virtual void Invoke(int value) { Delegate[] delegateSet = _invocationList as Delegate[]; if (delegateSet != null) { foreach (var d in delegateSet) { d(value); } } //==null 表示 不是委托链 else { //这行代码接近实际的代码 _methodPtr.Invoke(_target, value); } }
删除委托:
委托链不足的地方:
1.除了最后一个返回值,其他所有回调方法的返回值都会被丢弃;
2.如果被调用的委托中有一个抛出了异常或者阻塞了很长一段时间,那么后续的所有委托都调用不了.