.NET简谈委托链

简介: 说起链表大家都很熟悉,说起委托相信大部分的.NET程序员都也很了解;在平时的开发过程中经常会用到这两种技术,只不过链表在.NET里面已经被封装了,让我们用起来更加的方便就是集合类型Collection,在某种时候我们是有必要要了解这些方便而又快捷的背后是怎样封装的,委托是一种特殊的类型在.

说起链表大家都很熟悉,说起委托相信大部分的.NET程序员都也很了解;在平时的开发过程中经常会用到这两种技术,只不过链表在.NET里面已经被封装了,让我们用起来更加的方便就是集合类型Collection,在某种时候我们是有必要要了解这些方便而又快捷的背后是怎样封装的,委托是一种特殊的类型在.NET里面是用来作为方法的一种封装,在一些非托管的代码中如C++就没有这么幸运了,我们要面对是一些复杂的地址变换、链表的指针维护、内存的取址等等;微软一向都是人性化模仿的对象,不管是他的操作系统还是开发平台IDE做的都很舒服;可能有的人会说把程序员这么崇高而又神秘的职业该大众化了,是人都会写程序;这种问题大家仁者见仁,智者见智了;

今天我要说的就是.NET中的委托链,也许这个技术名词见的人很少,但是概念大家都能从字面上理解出来,那就是委托与链表的关系;简单点就是委托通过链表的方式将其保存,然后依次调用,关于委托与事件的可以参照本人的“委托与事件”文章;委托是指向方法的指针,将方法以对象的方式包装起来,方便、安全、异步的调用,在异步方面都是CLR通过后台线程去处理,我们不需要关心一些线程调度互斥等问题,特殊情况下也需要我们自己去从头封装;委托是一种类型,通过实例化多个委托实例去封装要调用的方法,在程序运行过程中每一个方法是被压入栈的数据结构中的,在调用之前先要确定方法的地址,所有通过引用类型将方法独立出来,方便寻找和调用;当多个委托实例聚集在一起的时候就形成了委托链这么一个数据结构,比如在我们经常使用的Button中一个Click事件,我们会通过:

Button.Click+=New 委托类型(方法1)将一个委托实例加入到委托链表中去,我继续添加一个方法到链表中去Button.Click+=New 委托类型(方法2),这个时候在委托链表中就有了两个委托实例了,也就是两个方法的调用;链表是有顺序的,方法2在方法1后面,代码的调用顺序就是先调用方法1让后将处理结果再带入到方法2中,处理依次进行,这样就形成了对委托链的整体调用;在使用时有一些细节需要注意也是性能的问题,“代码永远是危害程序性能的罪魁祸首”,在上述代码中Btton.Click+=New 委托类型(方法1),可以写成Button.Click+=方法1,这样就减少了一个委托实例的内存分配,系统将使用顺序表保存调用的方法,而不是链表,链表和顺序表在性能的区别我想学过<<数据结构>>的人都知道;当不需要使用链表中的某个方法时可以通过委托移除表达式将方法从委托链表中移除Button.Click-=方法1,我已经将方法1从委托链表中移除,当下次调用时,代码是不会走到方法1中的,在我们开发过程中经常会遇到这样的情况:一个事件发生了我要调用N个方法,但是我并不能控制这种执行顺序,这个时候我们就可以将方法从链表中移除或者添加,很方便的控制委托链中的方法执行前后顺序;也会遇到这种情况是什么呢,我有十个方法用来处理程序的逻辑,但是这十个方法不是死的我需要根据不同的条件从这十个方法中动态跳转到其他的逻辑处理中然后在回到该方法,程序永远不会脱离这十个方法,这个时候我们就需要用到委托参数了,这个时候我们需要定义一种类型用来在委托链表中传递,方法通过判断这个类型的实例的状态,确定是否继续向下传递;

图1:

 这个委托链中有4个方法,当我执行到方法2的时候我需要判断用户的输入是否正确,是否让后面的方法在继续执行:

public class Class1
    {
        /// <summary>
        /// 委托类型
        /// </summary>
        /// <param name="ismove">是否向下执行的标识</param>
        public delegate void Print(ref string ismove);
        /// <summary>
        /// 委托实例
        /// </summary>
        Print p;
        /// <summary>
        ///默认构造函数
        /// </summary>
        public Class1()
        {
            //添加四个方法
            Print p = new Print(method1);//第一个方法用来实例化委托第一个实例
            p += method2;
            p += method3;
            p += method4;
        }
        /// <summary>
        /// 开始执行委托链
        /// </summary>
        /// <returns></returns>
        public string run()
        {
            string ismove = "yes";
            p(ref ismove);
            return ismove;
        }
        public void method1(ref string ismove)
        {
            if (ismove == "yes")//判断是否要继续向下执行
            {

            }
        }
       public void method2(ref string ismove)
        {
            if (ismove == "yes")//判断是否要继续向下执行
            {
                //我这里执行出了问题,不想继续向下执行了
                ismove = "no";//后面的所有方法都不会执行
            }
        }

        public void method3(ref string ismove)
        {
            if (ismove == "yes")//判断是否要继续向下执行
            {

            }
        }
        public void method4(ref string ismove)
        {
            if (ismove == "yes")//判断是否要继续向下执行
            {

            }
        }

我们无法确定要移除哪一个方法,所以我们要确定每一次的方法调用都是正确的,方法的调用的会正常进行但是我们加入了判断这样就能控制执行的状态;

图2:

在图2中我将方法3和方法4从委托链中移除了,后面的调用将不会调用到他们;

 public class Class1
    {
        /// <summary>
        /// 委托类型
        /// </summary>
        /// <param name="ismove">是否向下执行的标识</param>
        public delegate void Print(ref string ismove);
        /// <summary>
        /// 委托实例
        /// </summary>
        Print p;
        /// <summary>
        ///默认构造函数
        /// </summary>
        public Class1()
        {
            //添加四个方法
            Print p = new Print(method1);//第一个方法用来实例化委托第一个实例
            p += method2;
            p += method3;
            p += method4;
        }
        /// <summary>
        /// 开始执行委托链
        /// </summary>
        /// <returns></returns>
        public string run()
        {
            string ismove = "yes";
            p(ref ismove);
            return ismove;
        }
        public void method1(ref string ismove)
        {
            if (ismove == "yes")//判断是否要继续向下执行
            {

            }
        }
        public void method2(ref string ismove)
        {
            if (ismove == "yes")//判断是否要继续向下执行
            {
                //这里已经处理完所有的逻辑,不需要在调用后面的调用
                p -= method3; //移除方法3
                p -= method4;//移除方法4
            }
        }
        /***********************后面的方法都不会被调用******************************************/
        public void method3(ref string ismove)
        {
            if (ismove == "yes")//判断是否要继续向下执行
            {

            }
        }
        public void method4(ref string ismove)
        {
            if (ismove == "yes")//判断是否要继续向下执行
            {

            }
        }
    }

目录
相关文章
.N“.NET研究”ET简谈委托链
  说起链表大家都很熟悉,说起委托相信大部分的.NET程序员都也很了解。在平时的开发过程中经常会用到这两种技术,只不过链表在.NET里面已经被封装了,让我们用起来更加的方便就是集合类型Collection。
790 0
一起谈.NET技术,.NET简谈委托链
  说起链表大家都很熟悉,说起委托相信大部分的.NET程序员都也很了解。在平时的开发过程中经常会用到这两种技术,只不过链表在.NET里面已经被封装了,让我们用起来更加的方便就是集合类型Collection。
826 0
|
Java 程序员 C#
一起谈.NET技术,从.NET中委托写法的演变谈开去(上):委托与匿名方法
在《关于最近面试的一点感想》一文中,Michael同学谈到他在面试时询问对方“delegate在.net framework1.1,2.0,3.5各可以怎么写”这个问题。于是乎,有朋友回复道“请问楼主,茴香豆的茴有几种写法”,“当代孔乙己”,独乐,众乐。
1019 0
|
监控 C#
一起谈.NET技术,浅谈.Net中容易混淆的委托和接口
  本文适合对委托和接口概念非常了解的朋友,并且欢迎各位朋友与Snake一起探讨有关这方面的知识.本文不适合对委托和接口概念或用途了解一知半解(模糊)的朋友,这篇文章可能会对您产生误导,请千万别看.   在文章正式开始之前我需要将MSDN上对委托和接口的内容放上来,作为文章之基.   委托:   委托是一种定义方法签名的类型。
953 0
|
C# UED
一起谈.NET技术,C#基础之委托异步
  大家知道委托就相当于C++里面的函数指针,相信大家都很很了解,看看如下简单代码来回想一下委托 public delegate void Ad(); xu xus = new xu(); Ad b = new Ad(xus.
830 0
|
C# UED
C#基础之“.NET研究”委托异步
  大家知道委托就相当于C++里面的函数指针,相信大家都很很了解,看看如下简单代码来回想一下委托 public delegate void Ad(); xu xus = new xu(); Ad b = new Ad(xus.
731 0
|
程序员
不要在using语句中“.NET研究”调用WCF服务
  如果你调用WCF服务时,像下面的代码这样在using语句中进行调用,需要注意一个问题。 using (CnblogsWcfClient client = new CnblogsWcfClient()){ client.Say("Hello, cnblogs.com!");}   上面这段代码看上去没问题,CnblogsWcfClient是一个自动生成的WCF客户端代理,继承自System.ServiceModel.ClientBase。
721 0
|
容器
.NET简谈观察者“.NET研究”模式
  观察者模式想必搞程序开发的都听说过,今天我也来简单的总结一下本人在程序开发过程中是怎么使用观察者模式的;希望给大家带来点新的想法,如果哪位高手看到了也不要嘲笑啊;呵呵,追求技术的人,始终都是为了技术而学技术,目的只有一个,一起追求技术的最高境界。
861 0
|
容器
.NET简谈观察者“.NET技术”模式
  观察者模式想必搞程序开发的都听说过,今天我也来简单的总结一下本人在程序开发过程中是怎么使用观察者模式的;希望给大家带来点新的想法,如果哪位高手看到了也不要嘲笑啊;呵呵,追求技术的人,始终都是为了技术而学技术,目的只有一个,一起追求技术的最高境界。
798 0
|
.NET C# C++
一起谈.NET技术,C# 委托,事件和Lambda表达式
  关于这个论题,Delegates, Events, and Lambda Expressions 对此有比较深入的分析,可以参考。C# vs C++之一:委托 vs 函数指针 比较了委托和C++指针的区别。
1016 0