委托的理解
来源:互联网 发布:淘宝详情图怎么加链接 编辑:程序博客网 时间:2024/05/18 01:26
委托
一、委托的使用
一个简单委托的构成
1.声明委托类型;
2.必须有一个方法包含了要执行的代码;
3.必须创建一个委托实例;
4.必须调用(invoke)委托实例;
以一个简单的计算类来介绍吧!首先,需要声明一个委托类型:
//声明委托public delegate int Calculate(int num1,int num2);
接下来,我们来实现委托所需要实现的方法,这里我在一个静态类中实现了加减乘除:
public static class NumCalculate { /// <summary> /// 加 /// </summary> /// <param name="num1"></param> /// <param name="num2"></param> /// <returns></returns> public static int Sum(int num1, int num2) { return num1 + num2; } /// <summary> /// 减 /// </summary> /// <param name="num1"></param> /// <param name="num2"></param> /// <returns></returns> public static int subtract(int num1,int num2) { return num1 - num2; } /// <summary> /// 乘 /// </summary> /// <param name="num1"></param> /// <param name="mun2"></param> /// <returns></returns> public static int mutiply(int num1,int num2) { return num1 * num2; } /// <summary> /// 除 /// </summary> /// <param name="num1"></param> /// <param name="num2"></param> /// <returns></returns> public static int divide(int num1,int num2) { if (num2==0) { return 0; } else { return num1 / num2; } } }
接下来,需要创建一个委托的实例:
//创建委托实例Calculate calculate = new Calculate(NumCalculate.Sum);
最后调用委托实例,就可以了。
int num1 = 6;int num2 = 3;int result = 0;result = calculate(num1, num2);
将结果输出后,可以看到result的值为:
委托的介绍
委托的原理
再来看一看刚才的委托声明:
//声明委托public delegate int Calculate(int num1,int num2);
根据CLR via C#的解释,编译器将会将会定义一个完整的类,通过ildasm反编译刚才生成的dll,就可以看到CLR所说的由编译器生成的类:
可以看到编译器定义的类有4个方法:一个构造器、BeginInvoke、EndInvoke和Invoke;并且可以看到这个类继承自System.MulticastDelegate。其实,当我们调用委托时,其实是调用的委托的Invoke方法。当然我们显示的调用Invoke方法也是可以得。
result = calculate.Invoke(num1,num2);
上面那行代码和前面的调用代码将会得到一样的结果。
委托的执行顺序
委托支持委托链,委托链就是委托对象的集合。当调用委托实例时,将会按顺序执行委托链中的方法。不过这里需要注意,当调用返回值不为void的委托实例时,返回值将是委托链中最后一个方法的值。将上面的代码修改成如下时:
Calculate calculate = new Calculate(NumCalculate.Sum);calculate += NumCalculate.divide;int num1 = 6;int num2 = 3;int result = 0;result = calculate(num1, num2);
运行程序,将会得到如下的结果:
为了进一步探究委托链的原理,在委托赋值完成之后加上断点。如下所示,可以看到_invovationList包含2个成员,即我们刚才添加的2个方法。当调用委托的实例时,将会按顺序执行这2个方法,并且将最后一个方法的返回值复制给result。
对于委托实例中方法的赋值和删除,可以很方便的使用+=和-=来实现,这2个操作符本质上是对Delegate类型的Combine和Remove静态方法的调用。
此外,CLR via C#还对委托的Invoke方法进行了实现,具体伪代码如下:
public Int32 Invoke(Int32 value1,Int32 value2){ Int32 result; Delegate[] delegateSet=_invocationList as Delegate[]; if(delegateSet!=null){ //这个委托数组指定了应该调用的委托 foreach(Calculate d in delegateSet) result=d(value1,value2);//调用每个委托 }else{ //否则就不是委托链 //该委托标识了要回调的回调单个方法, //在指定的目标对象上调用这个回调方法 result=_methodPtr.Invoke(_target,value1,value2); //上面这行代码接近实际的代码, //实际发生的事情用C#是表示不出来的 } return result;}
通过上面的伪代码,当数组中的每个委托被调用时,其返回值被保存到result变量中。循环完成后,result变量只包含调用的最后一个委托的结果(前面的返回值会被覆盖掉),该值最后会返回给调用Invoke的代码。这也说明了上面提到的:当调用返回值不为void的委托实例时,返回值将是委托链中最后一个方法的值。
总结
1.为了创建委托实例,需要一个方法以及(对于实例方法来说)调用方法的目标;
2.委托封装了包含特殊返回类型和一组参数的行为,类似于包含单一方法的接口;
3.委托实例可以合并到一起,也可以从一个委托实例中删除另一个;
4.每个委托实例都包含一个调用列表。
本文参考CLR via C#、深入理解C#
- 委托的理解
- 对委托的理解
- 关于委托的理解
- C# 委托的理解
- 委托的各种理解
- 委托的理解
- iOS委托的理解
- 关于委托的理解
- 关于委托的理解
- delegate委托的理解
- 委托的理解
- C#委托的理解
- C# 委托的理解
- 通过委托的实际应用理解委托
- 怎么理解委托?委托的特点是什么?
- 委托的理解 (抓小偷
- 委托的理解和使用
- 关于委托的理解1
- Activity基础
- Opencv3 python学习2——视频基础
- 模板方法模式(Template Method Pattern)。
- Android多媒体(音乐播放器)
- 数据结构和算法学习笔记
- 委托的理解
- HDOJ 1869 六度分离(Floyd 和 dijkstra 算法)
- JetSon Tx1 串口使用记录
- xiaze registration
- 为什么使用 SLF4J 而不是 Log4J 来做 Java 日志
- 思维导图
- Http请求连接池
- LINK:fatal error LNK1104: 无法打开文件“C:\Qt\4.8.0\lib\QtGuid4.lib”
- EFI模式下centos7扩容lvm Hyper-V