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();