我们能看到两种委托应用,代码都非常简洁 。
下面我们再来看委托的异步应用 。首先看最简单的异步调用 。
Action action = new Action(() => { });IAsyncResult result = action.BeginInvoke((iar) =>{}, null); Func<int> func = new Func<int>(() => { return 1; }); IAsyncResult resultfunc = func.BeginInvoke((iar) =>{ var res = func.EndInvoke(iar); }, null);这里我们使用委托的BeginInvoke方法来开启线程,进行异步调用 。如上面代码所示,这里介绍了Action与Func的最基础的异步应用 。
委托是架构的血液,如果系统中没有委托,那代码将堆叠到一起,耦合性就很高 。
就好比一碗汤面倒掉了所有的汤,只要它静放一个阵子,就会变成一坨面球,让你无从下嘴 。
所以,委托是是框架的流畅的基石 。
那么委托到底是如何流动的呢?
我们先从刚介绍过的委托的线程应用说起 。
第一核心应用——随手线程:
我们在做开发的时候,一定接触过父类 。父类是干什么的呢?父类通常是用来编写公共属性和函数,方便子类调用的 。
那我们的委托的第一个核心应用,就是父类的公共函数,线程随手启动 。如何随手开启呢?
首先,我们创建父类代码如下:
class BaseDelegateSyntax{public void AsyncLoad(Action action) {} public void AsyncLoad(Action action, Action callback) { IAsyncResult result = action.BeginInvoke((iar) => { callback(); }, null); } public void AsyncLoad<T>(Action<T> action, T para, Action callback) { IAsyncResult result = action.BeginInvoke(para, (iar) => { callback(); }, null); } public void AsyncLoad<T, R>(Func<T, R> action, T para, Action<R> callback) { IAsyncResult result = action.BeginInvoke(para, (iar) => { var res = action.EndInvoke(iar); callback(res); }, null); }}我们看到上面的代码,父类中添加了四个异步委托的调用函数,接下来,我们就可以在继承该类的子类中,随手开启线程了 。
子类代码如下:
class ChildDelegateSyntax : BaseDelegateSyntax{ public void Excute() { //开启异步方法 base.AsyncLoad(() => { });//开启异步方法,并且在异步结束后,触发回调方法 base.AsyncLoad(() => { }, ()=>{ //我是回调方法 });//开启异步有入参的方法,传递参数,并且在异步结束后,触发回调方法 base.AsyncLoad<string>((s) => { },"Kiba518", () => { //我是回调方法 });//开启异步有入参的方法,传递字符串参数Kiba518,之后返回int型结果518,//并且在异步结束后,触发回调方法,回调函数中可以获得结果518 base.AsyncLoad<string,int>((s) => { return 518; }, "Kiba518", (result) => { //我是回调方法 result是返回值518 }); }}看了上面的父子类后,是否感觉委托让我们繁杂的线程世界变简洁了呢?
第二核心应用——穿越你的世界:
接下来,我们来看委托的第二种核心用法,穿越的应用 。
这个应用,是最常见,也最普通的应用了 。因为委托是引用类型,所以A类里定义的委托,可以在被内存回收之前,被其他类调用 。
我们经常会在各种论坛看到有人发问,A页面如何调用B页面的属性、方法、父页面获取子页面的属性、方法,或者子页面获取父页面的属性、方法 。
其实,只要定义好委托,并将委托正确的传递,就可以实现穿越的调用了 。
下面我们看下穿越应用的代码 。
public class FirstDelegateSyntax{ public FirstDelegateSyntax() { Console.WriteLine(" First 开始 " ); SecondDelegateSyntax sds = new SecondDelegateSyntax(()=> { Console.WriteLine(" First传给Second委托被触发 "); }); sds.Excute(); Console.WriteLine(" First 结束 "); }} public class SecondDelegateSyntax{ public Action Action { get; set; } public SecondDelegateSyntax(Action _action) { Console.WriteLine(" Second的构造函数 "); Action = _action; } public void Excute() { Console.WriteLine(" Second的Excute被触发 "); Action(); }}我们可以看到,我们传递的委托,穿越了自身所属的类 。在SecondDelegateSyntax类中被触发了 。
运行结果如下:
文章插图
第三核心应用——回调函数:
世界上本没有回调函数,叫的人多了,也就有了 。
请记住,所有的回调函数,都是委托的穿越应用,所有的回调函数;都是委托的穿越应用;所有的回调函数,都是委托的穿越应用 。
重要的话要讲三遍 。
因为委托是引用类型,所以可以被[址传递] 。函数是不可以被传递的 。
当你传递函数的时候,其实是匿名传递了一个委托的地址 。
推荐阅读
- 编程核心知识—API与ABI的区别
- 计算机基本原理—语言与算法
- 香槟葡萄七姐妹——法国香槟酒背后葡萄品种的奥秘
- 北方小吃——鸡蛋饼的做法
- 压力,失眠,沮丧——周而复始
- 完美着装玉律——你应该选择正确的内衣
- 经典干邑,马爹利和轩尼诗— 它们的VSOP究竟有多不同?
- spring源码深度解析—容器的基本实现,你知多少?
- 音箱科普系列—音箱分频类型及优缺点,声音有些什么区别
- 翡翠|蟒带——赌色的生命带,不识蟒带何言赌石?