一起谈.NET技术,.NET简谈委托链

  说起链表大家都很熟悉,说起委托相信大部分的.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")//判断是否要继续向下执行
{
}
}
}

时间: 2024-07-31 17:58:38

一起谈.NET技术,.NET简谈委托链的相关文章

一起谈.NET技术,浅谈C#中的延迟加载(1)——善用委托

很久以前就听过延迟加载这个东西,不过没有理解是什么意思,现在算是了解一二了,写点文章作为读书笔记,把自己的想法记录一下,希望对初学者帮助,不管是初学者或者高手如果发现文章那里写得不好或者有更好的思路和做法记得告诉我哦^^.文章打算写成两三篇,这个是第一篇. 在三层结构中我们通常会使用多一个叫做模型层的东西,这一层中最主要做的事情是把数据库中的表 (或者其他数据源,例如xml或者自己定义的一种数据格式)转成对应的类,例如有一个文章表,这时候在这一层就会有一个文章类:文章类的属性对应着文章表的列,例

一起谈.NET技术,浅谈如何使用.NET存储XML数据

XML Bulk Load和Updategrams,这两种客户端技术使用带有注解的大纲指定XML文档内容和数据库的表之间的映射:OpenXML是一种服务器端技术,它允许你在XML文档上定义关系视图,有了OpenXML的关系视图,你就能使用T-SQL代码查询XML文档中的数据并把结果存储在你的SQL Server数据库中. 这三种技术中的每一种都是为特定的目的设计的.XML Bulk Load把来自很大的XML文档的数据存储在SQL Server中:Updategrams执行SQL Server数

一起谈.NET技术,浅谈C#中的延迟加载(2)——善用virtual

之前的文章"浅谈C#中的延迟加载(1)--善用委托"中介绍了三层结构中在Model层对实体类的属性实现延迟加载的方法,该方法利用C#中的委托来实现,最后虽然延迟加载的目的得以实现,但是给客户端(例如UI层)暴露了不必要的属性(一个委托对象,我使用了泛型的Fun类来实现).这篇文章介绍一种方法来隐藏这个属性,同时又可以达到延迟加载的目的,更重要的是这一切都是在之前的基础上来完成的,不需要改变原来使用到实体类的地方的代码. 按照惯例,我们考虑一下想要我们的代码达到什么效果:首先在Model

一起谈.NET技术,浅谈提升C#正则表达式效率

说到C#的Regex,谈到最多的应该就是RegexOptions.Compiled这个东西,传说中在匹配速度方面,RegexOptions.Compiled是可以提升匹配速度的,但在启动速度上,使用了RegexOptions.Compiled情况下,通常会使启动速度慢许多,据说最多是60倍. 进行一组测试,有测试数据,才有讨论依据. 第一步,帖上测试硬件信息(呵呵,硬件有点烂:() 第二步, a.测试在没有使用RegexOptions.Compiled项时候的情况,随意使用一些内容,然后循环一万

一起谈.NET技术,浅谈C#中的延迟加载(3)——还原模型的业务规则

上一篇文章讲到把实体类中需要实现延迟加载的属性声明为virtual,然后继承实体类做一个子类,在子类里面实现该属性,配合使用委托来实现比较完美的延迟加载(原本的模型层依旧保持在最底层用于贯穿三层结构,同时又可以实现在实体类的属性里面访问到比他高层的数据访问层).文章的最后依旧出现杯具,原因是在对模型的属性实现延迟加载之前,这个属性可能由于我们业务的需要,它并不单单是作为一个存储和读取的功能使用,而是在其get或者set的访问器中都包含这或许复杂或许简单的逻辑代码. 举例:考虑一下这个情景,我们有

只谈数据技术,不谈数据应用正确吗?

 企业使用大数据的普遍困境 中国的大数据建设发展真的很快. 前两年在和一些企业交流时,很多企业还在关注的是有哪些技术和厂商可以帮助自身做好大数据的整体架构.而近些日子中发现,越来越多的企业已经建立好了大数据平台或数据仓库及BI系统,而他们现在提的最多的一个问题是: "大数据基础建设投入不小,系统也上了,也做了不少报表和展示页面.但是业务部门和领导没觉得有什么用,没觉得大数据和传统报表有什么区别,也没觉得对业务有什么帮助和价值.现在感觉之前建好的系统越来越荒废了." 经过广泛的交流,我们

一起谈.NET技术,也谈ASP.NET 中的身份验证

一.配置安全身份验证模式 在Web.config 文件中,通过 <authentication> 节可以配置 ASP.NET 使用的安全身份验证模式,以标识传入的用户. <authentication mode="[Windows|Forms|Passport|None]"> <forms>...</forms> <passport/> </authentication> <authentication>

一起谈.NET技术,浅谈.Net中容易混淆的委托和接口

本文适合对委托和接口概念非常了解的朋友,并且欢迎各位朋友与Snake一起探讨有关这方面的知识.本文不适合对委托和接口概念或用途了解一知半解(模糊)的朋友,这篇文章可能会对您产生误导,请千万别看. 在文章正式开始之前我需要将MSDN上对委托和接口的内容放上来,作为文章之基. 委托: 委托是一种定义方法签名的类型.当实例化委托时,您可以将其实例与任何具有兼容签名的方法相关联.您可以通过委托实例调用方法. 委托用于将方法作为参数传递给其他方法.事件处理程序就是通过委托调用的方法.您可以创建一个自定义方

一起谈.NET技术,浅谈思路严谨的用户在线状态控制【附部分C#参考代码】

我们经常会遇到: 1:客户购买了5个用户的许可,10个用户的许可,软件需要限制用户的并发数量,我知道就是Oracle的并发用户达到20个以上,那费用是非常昂贵的. 2:一个用户只能登录一次或者是一个账号在同一时间只能登录一个,若已经是登录了就不让再登录了,需要能控制用户的并发登录问题. 3:有的系统也需要能实现在线用户列表.用户的登录状态等,特别是即时消息功能的内部管理系统等. 先把自己的思路整理图贴出来如下: C/S的部分参考代码如下:这里为了实现定时获取消息的平滑,利用了线程的方式,这样不影

一起谈.NET技术,浅谈ASP.NET MVC

在正式的工作中使用ASP.NET MVC也有一阵子了,也看了听了很多关于ASP.NET MVC别人的想法和代码,我认为很多人对于它的理解是错误的. 在这里我只谈谈对ASP.NET MVC我的一些想法,希望大家多多讨论. 1. ASP.NET MVC区别于ASP.NET在于设计理念 我听过的关于ASP.NET  MVC的第一个看法是ASP.NET MVC最大的特点在于Controller和View的分离,当时我还不懂ASP.NET MVC是什么东西,但是当我第一眼看到这个框架时,我就认为这个观点是