.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-10-10 14:52:55

.NET简谈委“.NET技术”托链的相关文章

.NET简谈面“.NET技术”向接口编程

过程式的开发方式已逐渐退出大众的眼线,随之而来的是各种各样的高抽象的开发模式:我们不得不承认在没有设计模式的时候,我们很难总结出有价值的开发模型,便于以后重复使用和推广:面向对象的流行,让我们开发人员重新站在一个高的起点来看待软件模型,抽象固然是好事,但是也给初学者带来了迷惑,将软件中的东西都想成很简单的封装,我们只需要调用就行,这样越来越多的开发人员开始慢慢的往上浮,有一定编程经验和感触的人,能够明白我所说的浮,也算是给初学者提个醒吧. 1: 2:  我们将计算机系统抽象层三个层次,我们做应

苹果高管简谈外部GPU技术 这说明了什么?

威锋网 4 月 5 日消息,在苹果公司举行的小型记者招待会上,苹果公司软件工程高级副总裁克雷格·费德里希回答了一个关于外部 Thunderbolt GPU 的问题,不过他的回答很简单,只有一句话,"我想它们会有属于自己的位置." 费德里希这个回答显然是经过一番斟酌的,虽然明确说出苹果正在开发这个概念,但是能让我们对苹果在这方面的行动稍有了解. 苹果与 eGPU 的兼容限制 在开发 Thunderbolt 3 协议的过程中,外部 PCI-E 接线盒增加了与 GPU 无缝连接的功能.通常笔

.NET简谈静态事件链

在我们日常开发过程中经常会遇到多个类实例之间的关联,不管是B/S还是C/S的项目,在对实例的使用是一样的:只不过C/S的项目比较好控制,不管是UI层的对象都能很好的控制,包括继承.重写等等:而在B/S里面可能不太方便,由于B/S本身的特点,不能暴露内部太多的继承关系,以免不小心破坏类的封闭性:我这篇文章主要是讨论在多个类实例之间怎么进行动态关联,比如我们在开发Winform项目的时候,可能会碰到两个或多个窗口之间协同工作的情况:本人在这种情况下采用的是静态事件链的解决方案,多个实例之间不存在主次

一起谈.NET技术,.NET简谈面向接口编程

过程式的开发方式已逐渐退出大众的眼线,随之而来的是各种各样的高抽象的开发模式:我们不得不承认在没有设计模式的时候,我们很难总结出有价值的开发模型,便于以后重复使用和推广:面向对象的流行,让我们开发人员重新站在一个高的起点来看待软件模型,抽象固然是好事,但是也给初学者带来了迷惑,将软件中的东西都想成很简单的封装,我们只需要调用就行,这样越来越多的开发人员开始慢慢的往上浮,有一定编程经验和感触的人,能够明白我所说的浮,也算是给初学者提个醒吧. 1: 2:  我们将计算机系统抽象层三个层次,我们做应

.NET简谈组件程序设计之(初识远程调用)

在.NET1.0版本出来的时候,要想进行远程调用基本上都是通过WebService的方式.而随着.NET2.0版本的出现,我们可以通过一个更加方便且高扩展性的框架来进行编写远程调用的程序,也就是我们都比较熟悉的.NetRemoting. 网上对.NetRemoting技术讲解的文章不计其数,但是很少有一本比较全面的.系统的学习书籍.我们都是从哪些零散的知识里慢慢摸索,效果不太理想. 今天我也来简单的介绍一下我理解的Remoting.不仔细研究一下还真不知道它的厉害,完全的托管平台.高扩展性.灵活

Facebook前主管谈大数据技术趋势和演变

本文讲的是Facebook前主管谈大数据技术趋势和演变,全球系统架构师大会于8月10-12日在深圳万科国际会议中心隆重举行.首先给大家带来分享的是前Facebook数据基础设施团队主管,Qubole创始人,CEO Ashish Thusoo,他主要介绍了大数据架构以及怎么样不断的演进,与其说演进,不如说革命.其中主要包括三个方面的主题: ▲全球系统架构师大会现场报道 第一,大数据的需求.当今世界需要大数据,有哪些驱动因素促使我们不同方式考虑大数据?以不同方式处理数据. 第二,技术给我们带来哪些架

.NET简谈互操作(五:基础知识之Dynamic平台调用)

互操作系列文章: .NET简谈互操作(一:开篇介绍) .NET简谈互操作(二:先睹为快) .NET简谈互操作(三:基础知识之DllImport特性) .NET简谈互操作(四:基础知识之Dispose非托管内存) .NET简谈互操作(五:基础知识之Dynamic平台调用) .NET简谈互操作(六:基础知识之提升平台调用性能) .NET简谈互操作(七:数据封送之介绍) 我们继续.NET互操作学习.在上篇文章中我们学习了关于托管与非托管内存Dispose(释放)问题:下面我们继续学习基础知识中的Dyn

.NET简谈平台大局观

在很久以前,我刚开始接触.NET的时候,总是搞不清楚.NET与VisualStudio之间的关系,我开发的东西是怎么样层层流转最终形成可执行文件的:这样的疑惑一直困扰着我,我想也困扰着许许多多刚接触.NET的开人员:尽管在学校的学生学过编译原理.操作系统等等计算机原理方面的理论知识:但是就是无法将这股力量用到实实在在的理解上:下面本人就简谈一下.NET中的主要核心东西:高级语言(C#,VB.NET,J#等).编译器.CLR引擎.VisualStudio系列工具等等之间是如何协调工作的,这样的理解

.NET简谈互操作(七:数据封送之介绍)

互操作系列文章: .NET简谈互操作(一:开篇介绍) .NET简谈互操作(二:先睹为快) .NET简谈互操作(三:基础知识之DllImport特性) .NET简谈互操作(四:基础知识之Dispose非托管内存) .NET简谈互操作(五:基础知识之Dynamic平台调用) .NET简谈互操作(六:基础知识之提升平台调用性能) .NET简谈互操作(七:数据封送之介绍) 我们继续.NET互操作学习.互操作的基础知识已经差不多完了,当然一篇小小的文章很难全面的讲述互操作的方方面面,本人只是总结出关键的地