看了《CLR via C#》的17章委托后,为自己做一点浅显的总结,也分享给需要的人。

.NET通过委托来提供一种回调函数机制,.NET委托提供了很多功能,例如确保回调方法是类型安全的(CLR重要目标)。委托好允许顺序调用多个方法(委托链),并且支持调用静态方法和实例方法。

委托的基本语法就不多说了。

internal delegate void Feedback(int value);
public sealed class Program{
publick static void Main(){ } private static void DelegateDemo(){
Counter(1,2,new Feedback(WriteToConsole));
Program p=new Program p();
Counter(1,2,new Feedback(WriteToMsgBox)); } private static void Counter(int from, int to, Feedback fb){
for(int i=from;i<to;i++){
if(fb!=null)
fb(i);
} } private static void WriteToConsole(int val){
Console.WriteLine(val); } private void WriteToMsgBox(int val){
MessageBox.Show(val)
} }

和普通调用静态方法实例方法没区别,如果需要回调静态方法,那么className.FuncName();   如果需要回调实例方法,那么Class_object.FuncName();

由于委托是类型安全的,它可以调用私用方法。

协变性和逆变性。

将一个方法绑定到委托的时候,C#和CLR都允许引用类型的协变性和逆变性,注意是引用类型哦。

delegate Object MyCallback(FileStream s);

string SomeMethod(Stream s);      //引用类型允许协变性,Stream是符合逆变性

int SomeOtherMethod(Stream s);   //值类型不允许协变性

协变性是指方法能返回从委托的返回类型派生的一个类型,不能用于void。逆变性是指方法获取的参数是委托的参数类型的基类。

委托链

Delegate.Combine(FirstDelegateObj,SecondDelegateObj);

FirstDelegateObj+=SecondDelegateObj;  //语法糖效果,等同于上一行

上面代码就是在构造委托链。

委托链的原理大概就是:维护MulticastDelegate类中的三个重要的非公共字段中的_invocationList.这个字段维护了委托数组。

另外两个字段就是_target.当委托包装了一个静态方法时,这个字段为null.当委托对象包装了一个实例方法时,这个字段引用的是回调方法要操作的对象。

_methodPtr  一个内部的整数值,CLR用它标识要回调的方法。

在很多时候,执行委托链的过程中可能遭遇其中某个方法的阻塞和异常影响接下来的方法的执行。这个时候,我们的解决办法是使用MulticastDelegate为我们提供的GetInvocationList方法,获取由委托引用组成的数组,

每个委托引用只想链中的一个委托对象。我们可以通过遍历来执行每一个委托。

委托链执行后只会返回最后一个回调方法所返回的值、

下面给出MulticastDelegate中Invoke方法的伪代码实现,这个方法解释了委托的执行过程和原理。

public int Invoke(int value)

{

      int result;

      Delegate[] delegateSet= _invoctionList as Delegate[];

      if(delegateSet !=null)

      {

          //委托链

          foreach(Feedback d in delegateSet)

          {

               result=d(value);

          }

      }

       else

      {

             //在执行对象上调用这个回调方法

              result= _methodPtr.Invoke(_target,value);

             //以上代码接近实际代码,但实际上C#表示不出来。

      }

      return result;

}

浅谈 C#委托的更多相关文章

  1. 浅谈C#委托和事件

    委托给了C#操作函数的灵活性,我们可使用委托像操作变量一样来操作函数,其实这个功能并不是C#的首创,早在C++时代就有函数指针这一说法,而在我看来委托就是C#的函数指针,首先先简要的介绍一下委托的基本 ...

  2. 浅谈C#委托和事件【转】

    委托给了C#操作函数的灵活性,我们可使用委托像操作变量一样来操作函数,其实这个功能并不是C#的首创,早在C++时代就有函数指针这一说法,而在我看来委托就是C#的函数指针,首先先简要的介绍一下委托的基本 ...

  3. 浅谈C#委托和事件(转载)

    委托给了C#操作函数的灵活性,我们可使用委托像操作变量一样来操作函数,其实这个功能并不是C#的首创,早在C++时代就有函数指针这一说法,而在我看来委托就是C#的函数指针,首先先简要的介绍一下委托的基本 ...

  4. 浅谈C#委托的用法-delegate[转]

    一.委托的概念 委托和类一样是一种用户自定义类型,它存储的就是一系列具有相同签名和返回类型的方法的地址,调用委托的时候,它所包含的所有方法都会被执行. 借用百度上的一句话概括:委托是一个类,它定义了方 ...

  5. 浅谈C#委托的用法-delegate

    2018年11月7日     小雨 一.委托的概念 委托和类一样是一种用户自定义类型,它存储的就是一系列具有相同签名和返回类型的方法的地址,调用委托的时候,它所包含的所有方法都会被执行. 借用百度上的 ...

  6. 【C#系列】浅谈委托和委托

    本篇文章更适合具有一定开发经验,一定功底,且对底层代码有所研究的朋友!!! 本篇文章主要采用理论和代码实例相结合方法来论述委托和事件,涉及到一些边界技术,如软件架构的OCP原则(开-闭原则), 软件架 ...

  7. 浅谈线程池(中):独立线程池的作用及IO线程池

    原文地址:http://blog.zhaojie.me/2009/07/thread-pool-2-dedicate-pool-and-io-pool.html 在上一篇文章中,我们简单讨论了线程池的 ...

  8. 浅谈线程池(上):线程池的作用及CLR线程池

    原文地址:http://blog.zhaojie.me/2009/07/thread-pool-1-the-goal-and-the-clr-thread-pool.html 线程池是一个重要的概念. ...

  9. 谁还没遇上过NoClassDefFoundError咋地——浅谈字节码生成与热部署

    谁还没遇上过NoClassDefFoundError咋地--浅谈字节码生成与热部署 前言 在Java程序员的世界里,NoClassDefFoundError是一类相当令人厌恶的错误,因为这类错误通常非 ...

随机推荐

  1. 【Hello CC.NET】CC.NET 实现自动化集成

    一.背景 公司的某一金融项目包含 12 个子系统,新需求一般按分支来开发,测完后合并到主干发布.开发团队需要同时维护开发环境.测试环境.模拟环境(主干).目前面临最大的两个问题: 1.子系统太多,每次 ...

  2. Web应用程序的自动化测试库-FluentAutomation

    FluentAutomation是流畅的自动化应用编程接口,支持Selenium和WatiN 连同它们所有的风格和驱动程序.自从Fluient支持Selenium,那就意味着你可以使用Selenium ...

  3. Entity Framework扩展库

    这个Entity Framework扩展完全支持EF 5.0/6.0,项目地址 https://github.com/loresoft/EntityFramework.Extended,这个库支持批量 ...

  4. 【腾讯Bugly干货分享】让 CodeReview 这股清流再飞一会儿

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/ToYeT4Y4pzx0ii9Z92fo-Q 作者:刘 ...

  5. WPF入门教程系列十九——ListView示例(一)

    经过前面的学习,今天我做一个比较综合的WPF程序示例,主要包括以下功能: 1) 查询功能.从数据库(本地数据库(local)/Test中的S_City表中读取城市信息数据,然后展示到WPF的Windo ...

  6. myeclipse转到函数定义的方法去

    转到函数的定义CTRl+鼠标左击 myeclipse自动补全的快捷键 alt+/

  7. Constraint3:check约束 和 null

    Check约束用以限制单列或多列的可能取值范围. 1,在check约束中(check(expression)),如果expression返回的结果是Unknown,那么check返回的结果是true. ...

  8. SSIS Design3:并发执行

    1,利用优先约束来并发处理数据,Data Flow Task 和 Data Flow Task 1 是并发执行的,而 Data Flow Task2 必须等到 Data Flow Task 和 Dat ...

  9. 【Win 10应用开发】认识一下UAP项目

    Windows 10 SDK预览版需要10030以上版本号的Win 10预览版系统才能使用.之前我安装的9926的系统,然后安装VS 2015 CTP 6,再装Win 10 SDK,但是在新建项目后, ...

  10. OpenCASCADE Interpolation - Lagrange

    OpenCASCADE Interpolation - Lagrange eryar@163.com Abstract. Power basis polynomial is the most simp ...