`
baobeituping
  • 浏览: 1042421 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

委托的相关概念

    博客分类:
  • .NET
阅读更多

委托提供了类似C++中函数指针的功能,简单地说委托类型就是面向对象函数指针,

不过C++的函数指针只能够指向静态的方法,

而委托除了可以指向一个静态的方法之外还可以指向对象实例的方法,并且委托是完全面向对象且使用安全的类型。

也就是说:委托可以看成是一种类型安全的函数指针,它用来代理一类符合其要求的方法(包括静态方法和动态方法即实例的方法),同时它又可以作为一个方法的参数进行传。

对“符合其要求”的解释:委托的 返回类型 和 参数 要与被代理的方法的 返回类型 和 参数 一致(不仅类型一致,参数个数也要相同)。

 

委托的优点:委托允许程序设计师可以在执行时期传入方法的名称动态地决定欲调用的方法,灵活性和扩张性非常强。

委托一般用在事件、多线程和通用类库中。

 

下面列举了5个示例对委托的概念和基本用法进行说明(这些例子来自陈广老师和楚广明老师的课堂,自己稍作了修改和融合)

为了省去创建GUI那些繁琐的步骤,更清晰地逼近委托的本质,接下来的所有程序都是控制台程序,程序最后的Console.ReadKey()是为了使程序中途停下来,以便看清楚执行过程中的输出。

 

一、

View Code
using System; //一、代理静态方法示例 namespace DelegateDemo { //委托的本质就是一个类,任何可以声明类的地方都可以声明委托 delegate void EatDelegate(string food);//委托的声明;其返回类型和参数要与被代理的方法的返回类型和参数一致 class MyDelegate { static void ZsEat(string food)//被代理的方法 { Console.WriteLine("张三吃:" + food); } static void LsEat(string food)//被代理的方法 { Console.WriteLine("李四吃:" + food); } static void WwEat(string food)//被代理的方法 { Console.WriteLine("王五吃:" + food); } static void Main(string[] args) { EatDelegate zsEat = new EatDelegate(ZsEat);//委托的实例化;代理的静态方法 zsEat("西瓜");//委托的使用; EatDelegate lsEat = LsEat;//代理的静态方法,直接将方法名传递给委托变量 lsEat("香蕉"); EatDelegate wwEat = new EatDelegate(WwEat);//委托的实例化;代理的静态方法 EatDelegate eatChain; Console.WriteLine("张三、李四、王五开座谈会"); eatChain = zsEat + lsEat + wwEat;//委托链 eatChain("西瓜"); Console.WriteLine(); Console.WriteLine("李四出去接电话"); eatChain -= lsEat; eatChain("香蕉"); Console.WriteLine(); Console.WriteLine("李四回来了"); eatChain += lsEat; eatChain("橘子"); Console.WriteLine(); Console.WriteLine("这是赵六来了"); eatChain += delegate(string food) { Console.WriteLine("赵六吃:" + food); };//匿名方法; eatChain("苹果"); Console.ReadKey(); } } }

输出结果:

二、

View Code
using System; //二、代理动态方法示例 namespace DelegateDemo { //委托的本质就是一个类,任何可以声明类的地方都可以声明委托 delegate void EatDelegate(string food);//委托的声明;其返回类型和参数要与被代理的方法的返回类型和参数一致 class Man { private string name; public Man(string name) { this.name = name; } public void Eat(string food)//被代理的方法 { Console.WriteLine(name + "吃:" + food); } } class MyDelegate { static void Main(string[] args) { Man zs = new Man("张三"); Man ls = new Man("李四"); Man ww = new Man("王五"); EatDelegate zsEat = new EatDelegate(zs.Eat);//委托的实例化;代理的动态方法,即实例的方法 zsEat("西瓜");//委托的使用; EatDelegate lsEat = ls.Eat;//代理的动态方法,直接将实例的方法名传递给委托变量 lsEat("香蕉"); EatDelegate wwEat = new EatDelegate(ww.Eat);//委托的实例化;代理的动态方法 EatDelegate eatChain; Console.WriteLine("张三、李四、王五开座谈会"); eatChain = zsEat + lsEat + wwEat;//委托链 eatChain("西瓜"); Console.WriteLine(); Console.WriteLine("李四出去接电话"); eatChain -= lsEat; eatChain("香蕉"); Console.WriteLine(); Console.WriteLine("李四回来了"); eatChain += lsEat; eatChain("橘子"); Console.WriteLine(); Console.WriteLine("这是赵六来了"); eatChain += delegate(string food) { Console.WriteLine("赵六吃:" + food); };//匿名方法; eatChain("苹果"); Console.ReadKey(); } } }

输出结果:与一相同。

三、

View Code
using System; //三、代理作为方法的参数示例 namespace DelegateDemo { delegate void EatDelegate(string food); class Man { private string name; public Man(string name) { this.name = name; } public void Eat(string food) { Console.WriteLine(name + "吃:" + food); } } class MyDelegate { static void EatTogether(string food, params EatDelegate[] values)//代理作为方法的参数进行传递 { if (values == null) { Console.WriteLine("座谈会结束"); } else { EatDelegate eatChain = null; foreach (EatDelegate value in values) { eatChain += value; } eatChain(food); } } static void Main(string[] args) { Man zs = new Man("张三"); Man ls = new Man("李四"); Man ww = new Man("王五"); EatDelegate zsEat = new EatDelegate(zs.Eat); EatDelegate lsEat = new EatDelegate(ls.Eat); EatDelegate wwEat = new EatDelegate(ww.Eat); Console.WriteLine("张三、李四、王五开座谈会"); EatTogether("西瓜", zsEat, lsEat, wwEat); Console.WriteLine(); Console.WriteLine("李四出去接电话"); EatTogether("香蕉", zsEat, wwEat); Console.WriteLine(); Console.WriteLine("李四回来了"); EatTogether("橘子", zsEat, lsEat, wwEat); Console.WriteLine(); EatTogether(null, null); Console.ReadKey(); } } }

输出结果:

四、

View Code
using System; //四、执行时传入方法的名称动态地决定欲调用的方法 namespace DelegateDemo { class MyDelegate { public delegate int GenericFun(int a, int b); public static int Add(int a, int b) { return a + b; } public static int Sub(int a, int b) { return a - b; } public static int PrintResult(GenericFun action, int a, int b)//执行时传入方法的名称动态地决定欲调用的方法 { int result = action(a, b); return result; } static void Main(string[] args) { Console.WriteLine("3+4=" + PrintResult(Add, 3, 4)); Console.WriteLine("3-4=" + PrintResult(Sub, 3, 4)); Console.ReadKey(); } } }

输出结果:

3+4=7

3-4=-1

五、

View Code
using System; //五、最后一个例子 namespace DelegateDemo { delegate int MathOperationsDelegate(int value); class MathOperations { public static int MultiByTwo(int value) { return value * 2; } public static int Square(int value) { return value * value; } } class MyDelegate { public static void ProcessAndDisplayRusult(MathOperationsDelegate action, int value) { int result = action(value); Console.WriteLine(result); } static void Main() { MathOperationsDelegate[] operations = { new MathOperationsDelegate(MathOperations.MultiByTwo), new MathOperationsDelegate(MathOperations.Square) }; for (int i = 0; i < operations.Length; i++) { Console.WriteLine("使用operation[{0}]", i); ProcessAndDisplayRusult(operations[i], 3); } Console.ReadKey(); } } }

输出结果:

使用operation[0]

6

使用operation[1]

9

<script type="text/javascript"></script>

分享到:
评论

相关推荐

    C#中 委托的详细讲解

    C#程序设计中有关委托的一些位内容:委托的概念 面向对象的核心思想之一就是将数据和对数据的操作封装为一个整体……

    C#中的委托的介绍,这是我自己的一些总结

    这个是我听讲完陈广老师的《C#程序设计入门与实例视频教程》中的委托后,自己写的笔记,自认为是写的很详细的了,反正以我目前的水平,感觉掌握这些有关委托的概念,应该是可以应用了,希望能对大家有点帮助。

    JQuery事件委托原理与用法实例分析

    主要介绍了JQuery事件委托原理与用法,结合具体实例形式分析了jQuery事件委托相关概念、原理及使用技巧,需要的朋友可以参考下

    JS中的事件委托实例浅析

    主要介绍了JS中的事件委托,结合实例形式简单分析了javascript事件委托的概念、功能、使用方法及相关注意事项,需要的朋友可以参考下

    C#委托浅析与漫谈

    而且从用途上讲主要也两方面:将“方法对象化”和实现“观察者模式”,本文围绕这两方面,分享本人对委托中相关概念的理解,顺便介绍一些相关的其它东西。  2. 闭包  闭包似乎在javascript里谈得比较多,其实...

    javascript相关事件的几个概念

    对于事件来讲,首先,我们需要了解这样几个概念:事件;事件处理程序;事件类型;事件流;事件冒泡;事件捕获;事件对象;事件方面的性能优化(事件委托、移除事件处理程序);常见的浏览器兼容问题。

    C#中委托用法实例分析

    主要介绍了C#中委托用法,较为详细的分析了C#中委托的概念与相关的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下

    objectory:对象工厂尊重 JavaScript 原型委托

    反对当被问及如果他必须从头开始重写 Java 时他会做些什么不同的事情时,James Gosling 建议他可以并编写语言。 资料来源:为什么存在当 ES6 到来时,类... 在这篇文章中阅读更多相关信息:它能做什么在 JavaScript 中

    C#实验报告七.docx

    1.理解程序错误和异常的概念。 2.掌握Visual Stdio.NET 2010的调试器的使用方法。 3.掌握C#的try-catch,finally,throw语句的使用方法。 二、实验要求 1.熟悉Visual Stdio.NET2010的基本操作方法。 2.认真阅读本章...

    PHP __call()方法实现委托示例

    主要介绍了PHP __call()方法实现委托,简单介绍了委托的概念、原理,并结合实例形式分析了__call()方法实现委托的相关操作技巧,需要的朋友可以参考下

    域、属性与事件

    域、属性与事件域的定义及使用 属性的概念 委托的概念与使用 事件

    股权代持、协议的相关风险.doc

     二、必须要区分投资权益和股东权益是两个不同的概念。  三、隐名投资人(即实际出资人)面临着股权被无权处分的巨大风险,对此,法院认定按照物权法关于无权处分的处理原则处理,那么隐名投资人将极有可能面临...

    关于信任的概念化和定义的共识:我们到了吗?-研究论文

    所有信托概念化是否以及在多大程度上需要风险、有意识地考虑风险、意愿和/或委托人和受托人的主动选择; 风险与信任的可分离性; 信任的心理与行为本质; 信任的认知与情感性质; 信任源于某些基础而不是其他基础的...

    【。net 专业】 面试题

    9.对于一个实现了IDisposable接口的类,以下哪些项可以执行与释放或重置非托管资源相关的应用程序定义的任务?(多选) ( ABC ) A.Close B.DisposeC.Finalize D.using E.Quit 10.Net依赖以下哪项技术实现跨语言互用性...

    Java多线程技术 线程的死锁,详细阐述了多线程的两种实现方法: 由Thread类派生子类;实现Runnable接口

    本文首先介绍了线程的有关概念,接着介绍了线程的生命期及其状态间的转换,多线程的调度 原则,线程的死锁,详细阐述了多线程的两种实现方法: 由Thread类派生子类;实现Runnable接口

    通信工程监理规范试题

    A、雇佣与被雇佣 B、委托与服务 C、委托与代理 D、领导与被领导 4.为项目监理组织实施目标控制建立前提条件,提供控制的依据、保障、措施、方法的工程建设监理文件是( B )。 A、监理大纲 B、监理规划 C、监理...

    设计模式-.NET并行编程

    《设计模式:NET并行编程》结合大量的项目实践,介绍了与并行编程相关的概念、方法和应用。本书共7章:第1章主要介绍并行编程的基本概念与并行计算的基础理论,第2章主要介绍并行循环的知识,第3章介绍并行任务处理...

    设计模式NET并行编程高清完整版带书签

    《设计模式:NET并行编程》结合大量的项目实践,介绍了与并行编程相关的概念、方法和应用。本书共7章:第1章主要介绍并行编程的基本概念与并行计算的基础理论,第2章主要介绍并行循环的知识,第3章介绍并行任务处理...

    股份代持协议(知名金融律师起草).docx

    在中华人民共和国相关法律规定范围框架内,双方现就本协议股份代持的有关事宜,经协商一致,达成如下协议: 一、股份代持关系的界定 1.1 为明确代持股份的所有权,甲、乙双方通过本协议确认,代持股份实际由甲方所有...

Global site tag (gtag.js) - Google Analytics