第23篇 委托的概述
什么是委托?
委托可以说是把一个方法代入另一个方法执行,相当于指向函数的指针;事件就相当于保存委托的数组;
1.实例化委托的方式:
方式1:通过new创建实例:
public delegate void ShowDelegate(); 或者 public delegate string ShowDelegate(string str);
ShowDelegate d = new ShowDelegate();
方式2:使用赋值的方式:
ShowDelegate s = test.show;
方式3:匿名委托
ShowDelegate s = delegate(){ console.WriteLine("匿名委托");}
2.使用委托
方式1:直接调用委托的变量,如:showDelegate("s",1);
方式2:invoke(),如showDelegate.invoke("s",2); //执行方法,如果委托定义没有参数,则invoke也没有参数,委托没有返回值,则invoke也没有返回值;
//BeginInvoke,开启一个线程去执行委托,netCore不支持,netframeWork支持,NetCore有更好的多线程功能来支持;
3.多播委托(委托链)
1)委托都是继承自MulicastDelegate(多播委托),定义的委托基本上都是多播委托;
2)可以通过+=把多个方法添加到这个委托中,形成一个执行链,按照添加的先后顺序依次执行;
3)可以通过-=把加入到委托的方法注销,
4)action.BeginInvoke()会开启一个新的线程去执行委托,注册多个委托时,不能使用beginInvoke()去执行;
5)注册有多个方法的委托想要开启新线程去执行委托,可以通过action.GetInvocationList()获取到所有的委托,然后循环执行,每个方法执行都可以用BeginInvoke;
4.多播委托使用的问题:
1)使用时,委托链的第一个方法报错了,导致后面注册的方法都是无法调用的,
解决方法:使用GetInvocationList按照调用顺序返回此多播委托调用的列表;
2)当委托链上,注册的都是有返回值的方法时,如果调用委托,那么只会返回最后一个注册的方法的返回值;
5.委托判断
在使用Invoke的时候:判断调用的委托是否为空,如果为空,不执行,不为空执行;
Delegate s = Show;
s -=Show;
s?.Invoke();
6.为什么使用委托:
1)委托时一种引用类型,表示对具体特定参数列表和返回类型的方法的引用,与C或者C++中的函数指针不同,
委托是一种面向对象,并且是类型安全的;
2)委托可以实现代码的重用,逻辑解耦,在方便代码维护的同时,方法声明和方法实现分离,也可提升程序的可扩展性;
7.泛型委托:与普通委托一样
public delegate void ShowDelegate<T,S>(T t,S s);
C#2.0提供了Action和Func两个泛型委托,不用申明,直接可用;
1)Action
public class ActionTest{
public Action Action;
public void SendMsg(){
console.writeline("消息发送完成!");
}
public void Test(){
//实例化方式有四种:
action = SendMsg;
action = new Action(SendMsg);
action = delegate(){
console.writeLine("delegate方式") //C#2.0提出用匿名函数代替;
}
action = ()=>{
console.writeLine("lambda 匿名方法") //C#3.0提出用lamda表达式写
}
action();
action.Invoke();
}
}
2)Func与Action写法类似;
8.什么是事件
1)事件是基于委托的,为委托提供一个订阅或发布的机制,是一种特殊的委托,调用事件和委托是一样;
public event DoDelegate DoEvent;
9.委托与事件的区别?
1)事件只能在方法的外部进行声明,而委托内外部都可以;
2)事件只能在类的内部进行触发,不能在类的外部进行触发,而委托在类的内外部都可以触发;
3)委托一般是用于回调,而事件一般是用于外部接口;