`
weiyinchao88
  • 浏览: 1234342 次
文章分类
社区版块
存档分类
最新评论

学习笔记36(委托)

 
阅读更多

委托的概念

委托实际上是类(一个貌似函数一样的类),我们已经使用函数指针很多年了——函数指针也被称为过程类型,但是它们的实现都不是类。它们是单独的函数指针的简单实例。委托是包含这些功能的类,委托类通过保留的列表来确定某些事物是否已经指派给了委托,这种算法可以理解为:“对于内部列表中的每一个回调函数,都调用函数”。委托除了支持回调函数外,还可以通过该列表来实现多播(委托链)。

说白了,就是我们把一批具有相同特征的方法,通过建立与具有同样相同特征的委托的一个实例来进行传递,以使其它地方能对这些方法进行调用。即把方法当作参数进行传递(浅显的认识,勿笑)。

初识委托

示例1:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

usingSystem.Web;

namespaceMyDelegateTest

{

///<summary>

///说明:一个简单的委托示例

///作者:文野

///联系:stwyhm.cnblogs.com

///</summary>

//新建一个用以输出消息的委托

publicdelegatevoidWriteMessage();

publicclassWriteToWeb

{

//一个输出消息的静态方法

publicstaticvoidStaticWrite()

{

HttpContext.Current.Response.Write("委托调用了一个静态方法。<br />");

}

//一个输出消息的类实例方法

publicvoidWrite()

{

HttpContext.Current.Response.Write("委托调用了一个类实例方法。<br />");

}

}

}

调用:

protectedvoidPage_Load(objectsender,EventArgse)

{

//新建一个委托,回调函数是一个静态方法

WriteMessagewm =newWriteMessage(WriteToWeb.StaticWrite);

WriteToWebw =newWriteToWeb();

//新建一个委托并与加到先前建立的委托组成委托链,回调函数是一个类实例方法

wm +=newWriteMessage(w.Write);

//执行委托链上所有的回调函数

wm();

}

上面的示例程序首先建立了一个简单得不能再简单的用以输出的委托,下面的类中有两个与委托签名一致的方法(一个静态方法,一个类实例方法)。下面的调用过程首先建立了一个使用回调静态方法的委托,其后又建立了一个使用类实例方法的委托并与先前的委托组成了一个委托链,最后执行委托链上所有的方法。

由此可见,委托最简单的理解就是利用与方法签名一致的委托,可以把方法当作参数一样来传递,无论是静态方法还是类实例方法。

委托的秘密


从上面的类视图中我们看到,对委托的定义最终被编译成一个类,这个类中定义有4种方法:构造器,Invoke,BeginInvoke,EndInvoke。

所有的委托都继承自MulticastDelegate,而MulticastDelegate又继续至Delegate。这样我们定义的委托自然也就继承了MulticastDelegate的字段、属性和方法。在继承得到的所有成员中,有3个最重要的字段:

1、_target:指向调用回调函数时应该操作的对象。该字段用于实例方法的回调。

2、_methodPtr:一个内部的整数值,CLR用它来识别回调的方法。

3、_prev:指向另一个委托对象。

当编译器知道我们在构造的是一个委托时,它会分析源代码来确定要引用哪个对象和方法。其中对象引用会被传递给_target(对于静态方法,_target被置为null),一个特殊的标识方法的Int32值会被传递给_methodPtr,_prev在构造器中被置为null,它被用于在委托链中记录下一个委托的引用。

每个委托对象实际上是对方法及其调用操作的一个包装,MulticastDelegate中定义了两个只读属性,Target和Method,Target(其实就是前面的_target字段)属性返回一个方法回调时操作的对象的引用,Method属性返回一个标识回调方法的System.Reflection.MethodInfo对象。

委托链

前面介绍过MulticastDelegate中有一个_prev的私有字段,这个字段指向另一个MulticastDelegate对象的引用,这样就实现了委托链(其实与我们在学链表时的实现方式是一致的)。

当委托链表被调用时,它首先会调用委托中在其前面的委托对象,这里如果被调的回调方法具有返回值,将被丢失,委托链只会返回最后一次调用回调方法的返回值。

委托示例

这是一个我自认为比较经典的委托示例(给排序算法传递一个动态比较的函数)。

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceMyDelegateTest

{

///<summary>

///说明:给排序算法传递一个动态比较函数的委托示例

///作者:文野

///联系:stwyhm.cnblogs.com

///</summary>

//进行排序的委托

publicdelegateboolCompare(intleft,intright);

publicclassDelegateSample

{

privateint[] items;

publicint[] Items

{

set{ items =value; }

get{returnitems; }

}

//比大

publicboolGreater(intleft,intright)

{

returnleft > right;

}

//比小

publicboolLess(intleft,intright)

{

return!Greater(left, right);

}

publicvoidSort(Comparecompare)

{

for(inti = 0; i < items.Length-1; i++)

{

for(intj = i + 1; j < items.Length; j++)

{

if(compare(items[i], items[j]))

{

inttmp = items[i];

items[i] = items[j];

items[j] = tmp;

}

}

}

}

}

}

调用页面

usingSystem;

usingSystem.Data;

usingSystem.Configuration;

usingSystem.Collections;

usingSystem.Web;

usingSystem.Web.Security;

usingSystem.Web.UI;

usingSystem.Web.UI.WebControls;

usingSystem.Web.UI.WebControls.WebParts;

usingSystem.Web.UI.HtmlControls;

usingMyDelegateTest;

publicpartialclassSort: System.Web.UI.Page

{

protectedvoidPage_Load(objectsender,EventArgse)

{

}

protectedvoidButton1_Click(objectsender,EventArgse)

{

DelegateSamplesample =newDelegateSample();

sample.Items = GetItems();

//使用降序

sample.Sort(newCompare(sample.Less));

PrintItems(sample);

}

privatevoidPrintItems(DelegateSamplesample)

{

for(inti = 0; i < sample.Items.Length; i++)

{

Response.Write(sample.Items[i] +"<br/>");

}

}

privateint[] GetItems()

{

string[] str =this.TextBox1.Text.Split(",".ToCharArray());

int[] items =newint[str.Length];

for(inti = 0; i < str.Length; i++)

items[i] =int.Parse(str[i]);

returnitems;

}

protectedvoidButton2_Click(objectsender,EventArgse)

{

DelegateSamplesample =newDelegateSample();

sample.Items = GetItems();

//使用升序

sample.Sort(newCompare(sample.Greater));

PrintItems(sample);

}

}

效果图:

降序



升序


参考资料:

《.NET框架程序设计》

《Visual Basic .Net Power Coding》

分享到:
评论

相关推荐

    VS.NET学习笔记

    【VS.NET学习笔记】 Visual Studio .NET(简称VS.NET)是微软公司开发的一款强大的集成开发环境,用于构建基于.NET Framework的应用程序。这个平台为开发者提供了丰富的工具和功能,支持多种编程语言,如C#、VB.NET...

    C#学习笔记

    以下是对C#学习笔记的详细解读: 1. **基础语法**:C#的基础包括变量、数据类型(如整型、浮点型、布尔型、字符串等)、运算符(算术、比较、逻辑、赋值等)和控制结构(如条件语句、循环语句、switch语句)。初学...

    C#的学习笔记总结

    C#学习笔记总结 本文档旨在总结C#的学习笔记,涵盖了C#的基本特征、语法、泛型、多线程、集合、反射等重要知识点。 一、C#的基本特征 C#是一门面向对象的语言,具有面向对象的基本特征,包括抽象、封装、继承、...

    java基础学习笔记

    ### Java基础学习笔记知识点 #### 一、Java学习路线概览 Java学习通常分为几个阶段,从基础到高级,逐步深化。以下是对给定文件中提到的学习路线的详细解析: ##### 第一阶段:Java基础 - **JAVASE**:Java标准版...

    .NET学习笔记

    .NET学习笔记是对初学者入门和提升技能的重要资源,它涵盖了.NET框架的核心概念和技术。这篇笔记主要涉及了Asp.NET开发、C#编程以及一般性的IT知识。 首先,我们来看看"Asp.net开发必备51种代码(非常实用).doc"。这...

    C#-学习笔记

    在深入探讨"C#高级编程"的学习笔记之前,我们先来理解一下C#这门语言的基础。C#(读作"C sharp")是由微软公司开发的一种面向对象的编程语言,主要用于构建Windows应用程序、Web应用以及移动应用。它在.NET框架或...

    经典、简单C#学习笔记

    综上所述,"经典、简单C#学习笔记"涵盖了C#语言从基础到进阶的全面内容,适合初学者入门,也对有一定经验的开发者有参考价值。通过深入理解和实践这些知识点,你将能够熟练掌握C#,并在各种应用场景中游刃有余。

    Visual c#学习笔记

    《Visual C#学习笔记》是一本深入探讨C#编程语言及其在ASP.NET框架下应用的专业教程。这本书旨在为想要掌握C#和ASP.NET技术的读者提供详尽的指导,无论你是初学者还是有一定开发经验的程序员,都能从中受益匪浅。 ...

    达内Unity课程四个月学习笔记

    以下是根据这四个月学习笔记中的关键内容所提炼的详细知识点: 一月内容主要涉及Unity的基础知识: 1. Unity界面介绍:包括项目窗口、资产面板、层次视图、Inspector窗口、场景视图等基本元素的使用。 2. ...

    JavaScript基础学习笔记

    JavaScript 基础学习笔记 本资源摘要信息基于黑马视频记录的学习笔记,涵盖了 JavaScript 基础知识点,包括 HTML、CSS、JavaScript、DOM、事件处理等内容。 HTML 和 CSS 基础 * HTML 结构:head、body、title、...

    c++学习笔记.pdf

    2. C++中的构造函数有几种类型:默认构造函数、拷贝构造函数、委托构造函数等。构造函数是在创建对象时自动调用的特殊成员函数,用于初始化对象的成员变量。 3. 结构体内存对齐是C++中为了提高内存存取效率而采取的...

    C#学习笔记(非常经典)

    C#学习笔记因其经典性和实用性而受到许多程序员的推崇,是初学者入门和进阶的重要参考资料。 在C#的学习过程中,首先需要理解其基本语法结构,包括变量定义、数据类型(如int、string、bool等)、控制流(如if语句...

    U8财务知识学习笔记.doc

    《U8财务知识学习笔记》是一份详细的财务学习资料,主要涵盖了会计基础知识、会计原则、会计科目、借贷记账法、会计恒等式、资产计量、存货管理、固定资产折旧、财务报表等内容。 首先,会计科目是根据经济业务的...

    spring学习笔记

    ### Spring学习笔记知识点详解 #### 一、Spring框架概述 **Spring** 是一个开源的、分层的企业级应用开发框架,旨在简化Java EE应用程序的开发。它的主要目标是提高开发效率,减少耦合度,并提供一种更为简洁的...

    dojo学习笔记

    Dojo 是一个强大的JavaScript工具库,它为Web开发提供了丰富的功能和组件,包括AJAX、DOM操作、动画...在“dojo学习笔记”中,你可能找到了关于这些概念的详细讲解和实践案例,这对理解和掌握Dojo技术体系非常有帮助。

    韩顺平jquery学习笔记及练习

    《韩顺平jQuery学习笔记及练习》是一份珍贵的学习资源,由知名讲师韩顺平的课程实录整理而成,旨在帮助学习者深入理解和掌握jQuery这一强大的JavaScript库。jQuery简化了HTML文档遍历、事件处理、动画设计和Ajax交互...

    性能测试学习笔记之LoadRunner实战.docx

    ### 性能测试学习笔记之LoadRunner实战 #### 第1章 一切从零开始 **1.1 拒绝性能测试的理由** 在探索性能测试的过程中,很多人可能会因为种种原因而选择回避或延迟开始。本章节列出了几种常见的拒绝理由,并试图...

    java之jvm学习笔记五(实践写自己的类装载器)

    这个“java之jvm学习笔记五(实践写自己的类装载器)”很可能是对这一主题的详细探讨。 类装载器在Java中的主要职责是动态加载类到JVM中。Java的类装载器分为三个基本层次:启动类装载器(Bootstrap ClassLoader)、...

    C#学习笔记powerpoint版

    **C#学习笔记PowerPoint版概述** 这是一份基于PowerPoint制作的C#学习笔记,适合初学者系统地了解和掌握C#编程语言的基础知识。虽然没有具体的描述,但我们可以推测这份笔记是作者在学习过程中整理的心得体会,旨在...

Global site tag (gtag.js) - Google Analytics