1 前言

本系列会将【委托】 【匿名方法】【Lambda表达式】 【泛型委托】 【表达式树】 【事件】等基础知识总结一下。(本人小白一枚,有错误的地方希望大佬指正)

系类1:细说委托

系类2:细说匿名方法

系列3:细说Lambda表达式

系列4:细说泛型委托

系列5:细说表达式树

系列6:细说事件

前几天看到博客园一个前辈写了一篇文章用“五分钟重温委托,匿名方法,Lambda,泛型委托,表达式树”,文章写的非常好,推荐阅读一下,正所谓“前人栽树,后人乘凉”,在这我就站在巨人的肩上,再将这几个概念加上“事件”这一概念在复习一遍,一来是加深记忆,二来方便后来人学习,本人小白一枚,有错的地方希望老司机指正。

2 什么是委托

委托是一个类,使得可以将方法当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。

用最通俗易懂的话来讲,你就可以把委托看成是用来执行方法(函数)的一个东西。

3 初识委托

我们知道委托是一个引用类型,所以它具有引用类型所具有的通性。它保存的不是实际值,而是保存对存储在托管堆(managed heap)中的对象的引用。那它保存的是对什么的引用呢?委托保存的是对函数(function)的引用。

对学过C/C++的人,是不是觉得跟函数指针很像呢!委托可以引用实例和静态(在 Visual Basic 中为 Shared)方法,而函数指针只能引用静态方法。 其实它们是有区别的,在非托管C/C++中,函数的地址就是一个内存地址。该地址不会携带任何额外的信息,例如函数期望的参数个数、参数类型、函数的返回值类型及函数的调用约定。总之,非托管C/C++中函数指针是非类型安全的。而.NET中的委托是类型安全的,委托会检测它所保存的函数引用是否和声明的委托匹配。

4 委托的使用

在使用委托的时候,你可以像对待一个类一样对待它。即先声明,再实例化。只是有点不同,类在实例化之后叫对象或实例,但委托在实例化后仍叫委托。

下边的代码,完成了一个委托使用的演示。一个委托分三个步骤:

step01:首先用delegate定义一个委托 。

step02:声明一个方法来对应委托。

step03:用这个方法来实例化这个委托。

  1. namespace Delegate
  2. {
  3. class Program
  4. {
  5. //step01:首先用delegate定义一个委托 。
  6. public delegate int CaculateAdd(int x, int y);
  7. static void Main(string[] args)
  8. {
  9. //step03:用这个方法来实例化这个委托。
  10. CaculateAdd add1 =new CaculateAdd(Add);
  11.  
  12. //int result = cAdd.Invoke(5, 6);
  13. int result = add1(, );
  14.  
  15. Console.WriteLine(result);
  16. Console.ReadKey();
  17. }
  18. // step02:声明一个方法来对应委托。
  19. public static int Add(int x,int y)
  20. {
  21. return x + y;
  22. }
  23. }
  24. }

到这里,你就基本上会用委托了。是不是很简单。

来解析一下委托类:

当我们用delegate关键字声明委托时,编译器自动为我们生成类

类的名字即为委托变量名,访问类型为定义的委托访问类型

如:

public delegate int CaculateAdd(int x, int y);定义的委托对应的类为 CaculateAdd,访问类型为public,该类继承自[mscorlib]System.MulticastDelegate。

如果我们定义委托的访问类型为private或者protected,则对应的委托类的访问类型为private或者protected。

但是任何委托都继承自[mscorlib]System.MulticastDelegate。

5 委托的多播(Multicasting of a Delegate)

委托对象可使用 "+" 运算符进行合并。一个合并委托调用它所合并的两个委托。只有相同类型的委托可被合并。"-" 运算符可用于从合并的委托中移除组件委托。

使用委托的这个有用的特点,您可以创建一个委托被调用时要调用的方法的调用列表。这被称为委托的 多播(multicasting),也叫组播。下面的程序演示了委托的多播:

  1. using System;
  2.  
  3. delegate int NumberChanger(int n);
  4. namespace DelegateAppl
  5. {
  6. class TestDelegate
  7. {
  8. static int num = ;
  9. public static int AddNum(int p)
  10. {
  11. num += p;
  12. return num;
  13. }
  14.  
  15. public static int MultNum(int q)
  16. {
  17. num *= q;
  18. return num;
  19. }
  20. public static int getNum()
  21. {
  22. return num;
  23. }
  24.  
  25. static void Main(string[] args)
  26. {
  27. // 创建委托实例
  28. NumberChanger nc;
  29. NumberChanger nc1 = new NumberChanger(AddNum);
  30. NumberChanger nc2 = new NumberChanger(MultNum);
  31. nc = nc1;
  32. nc += nc2;
  33. // 调用多播
  34. nc();
  35. Console.WriteLine("Value of Num: {0}", getNum());
  36. Console.ReadKey();
  37. }
  38. }
  39. }

当上面的代码被编译和执行时,它会产生下列结果:

Value of Num: 75

6 总结

至此,委托的基本知识和应用就已经很清楚了。下一篇将介绍匿名方法。详见:

参考文献:

博客

菜鸟

百度百科

友情提示

作者:mhq_martin

博客园地址:http://www.cnblogs.com/mhq-martin/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

【C#复习总结】细说委托的更多相关文章

  1. 【C#复习总结】细说泛型委托

    1 前言 本系列会将[委托] [匿名方法][Lambda表达式] [泛型委托] [表达式树] [事件]等基础知识总结一下.(本人小白一枚,有错误的地方希望大佬指正) 系类1:细说委托 系类2:细说匿名 ...

  2. 【C#复习总结】细说表达式树

    1 前言 系类1:细说委托 系类2:细说匿名方法 系列3:细说Lambda表达式 系列4:细说泛型委托 系列5:细说表达式树 系列6:细说事件 涛声依旧,再续前言,接着用大佬的文章作为开头. 表达式树 ...

  3. 【C#复习总结】细说 Lambda表达式

    1 前言 本系列会将[委托] [匿名方法][Lambda表达式] [泛型委托] [表达式树] [事件]等基础知识总结一下.(本人小白一枚,有错误的地方希望大佬指正) 系类1:细说委托 系类2:细说匿名 ...

  4. 【C#复习总结】细说匿名方法

    1 前言 本系列会将[委托] [匿名方法][Lambda表达式] [泛型委托] [表达式树] [事件]等基础知识总结一下.(本人小白一枚,有错误的地方希望大佬指正) 系类1:细说委托 系类2:细说匿名 ...

  5. 委托学习笔记后续:泛型委托及委托中所涉及到匿名方法、Lambda表达式

    引言: 最初学习c#时,感觉委托.事件这块很难,其中在学习的过程中还写了一篇学习笔记:委托.事件学习笔记.今天重新温故委托.事件,并且把最近学习到和委托相关的匿名方法.Lambda表达式及泛型委托记录 ...

  6. 泛型委托及委托中所涉及到匿名方法、Lambda表达式

    泛型委托及委托中所涉及到匿名方法.Lambda表达式 引言: 最初学习c#时,感觉委托.事件这块很难,其中在学习的过程中还写了一篇学习笔记:委托.事件学习笔记.今天重新温故委托.事件,并且把最近学习到 ...

  7. 细说并发编程-TPL

    本节导航 基本概念 并发编程 TPL 线程基础 windows为什么要支持线程 线程开销 CPU的发展 使用线程的理由 如何写一个简单Parallel.For循环 数据并行 Parallel.For剖 ...

  8. c#中@标志的作用 C#通过序列化实现深表复制 细说并发编程-TPL 大数据量下DataTable To List效率对比 【转载】C#工具类:实现文件操作File的工具类 异步多线程 Async .net 多线程 Thread ThreadPool Task .Net 反射学习

    c#中@标志的作用   参考微软官方文档-特殊字符@,地址 https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/toke ...

  9. c#委托(Delegates)--基本概念及使用

    在我这菜鸟理解上,委托就是可以用方法名调用另一方法的便捷方法,可以简化switch等语句的重复.最近做项目的时候恰好需要用到委托,便来复习及学习委托的使用.嗯...本人以前并没有用过,只是稍微知道而已 ...

随机推荐

  1. java基础(五) String性质深入解析

    引言   本文将讲解String的几个性质. 一.String的不可变性   对于初学者来说,很容易误认为String对象是可以改变的,特别是+链接时,对象似乎真的改变了.然而,String对象一经创 ...

  2. (后端)解决code唯一码(java)简便方法

    public String next() { long appBootTimes = systemVariableService.getAppBootTimes(); return Long.toSt ...

  3. Caused by:org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type "" available: expected at least 1 bean which qualifies as autowire candidate

    项目使用spring, mybatis.因为分了多个模块,所以会这个模块引用了其它模块的现在,结果使用Junit测试的时候发现有两个模块不能自动注入dao和service问题.解决后在此记录一下. 解 ...

  4. exports与module.exports的区别,export与export.defult区别

    在JS模块化编程中,之前使用的是require.js或者sea.js.随着前端工程化工具webpack的推出,使得前端js可以使用CommonJS模块标准或者使用ES6 moduel特性. 在Comm ...

  5. 搭建的flask项目,若修改项目中的文件,项目没有reload,除非重启主机,解决方法如下

    1.博主本人前面有发过一篇博文如何搭建flask项目,可以去查看. 解决办法:加入一句 touch-reload=项目目录在uwsgi.ini 2.测试没问题

  6. SSL里的certificate格式资料小结

    在查看相关报文的时候,发现RFC5246本身并没有对certificate的格式AlgorithmIdentifier作深入的介绍,只说其格式必须是X509v3 DER表示,思虑良久才找到方向:后者的 ...

  7. 如何定位那些SQL产生了大量的redo日志

    在ORACLE数据库的管理.维护过程中,偶尔会遇到归档日志暴增的情况,也就是说一些SQL语句产生了大量的redo log,那么如何跟踪.定位哪些SQL语句生成了大量的redo log日志呢? 下面这篇 ...

  8. spring4笔记----常见的java的字符类型与xml匹配

    private List<String> schools; <property name="schools"> <list> <value ...

  9. 利用fpm制作rpm包

    使用fpm制作rpm包 安装如下 [root@web01 ~]# yum install -y gcc zlib zlib-devel wget http://ruby.taobao.org/mirr ...

  10. Ubuntu 12.04上安装R语言

    Ubuntu 12.04上安装R语言 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ R的安装 sudo gedit /etc/apt/sources. ...