1.委托delegate
委托实例是调用者的委托:调用者调用委托,委托调用目标方法;
把调用者和目标方法解藕;
2.多播委托
所有委托实例都有多播的方法,即一个委托实例可以有多个目标方法;
委托调用顺序与定义顺序一致;
如果方法返回值不是void,则只会接受到最后一个目标方法的返回值;
使用+=和-=来增减订阅的方法,会被编译成system.delegate的combine和remove静态方法;
所有的委托都是派生自system.MultiCastDelegate,它是派生自system.Delegate;
3. 实例方法目标和静态方法目标
实例方法赋值给委托实例时,不仅保留对方法的音乐还要保留对该实例的引用;
system.delegate的Target属性就对应于该实例;
如果引用方法时静态的,则target时null;
4.范型委托类型,Func和Action:
public delegate T tansformer<T>(T arg);
Func和Action最多16个输入参数:
delegate TResult Func<in T1,...in T16, out TResult>(T1 arg1, ..., T16 arg16);
delegate void Func<in T1,...in T16>(T1 arg1, ..., T16 arg16);
5. 接口vs委托:
委托可以解决的问题,接口一般也可以解决,但是
委托可以多播,而接口一般只能实现一种方法,所有在多播的场景议案使用委托;
6. 委托兼容性
所有的委托都是类型不兼容的;
delegate void T1(); delegate void T2(); void method(){...} T1 t1 = method; T2 t2 = t1; //会报编译错误如果委托实例具有相同的委托方法,那么委托实例就可以认为是相等的
delegate void D(); D d1 = method; D d2 = method; Debug.WriteLine(d1==d2); //返回true委托可以接受比方法定义更加具体的参数,叫做ContraValue逆变(仅适用于引用转换而不是值类型转换);
委托方法可以返回一个比委托定义中更具体的方法,叫做Convariance协变
//ContraValue delegate void D(string s); void method(object o){...} D d = method; d("hello"); //Convariancce delegate object D(); string method(){return "hello";} D d = method; string res = d();