托付是寻址方法的.NET版本号。在C++中。函数指针仅仅只是是一个指向内存位置的指针,它不是类型安全的。而.NET托付全然不同,托付是安全类型的类,它定义了返回类型和參数的类型。

当把方法传递给其它方法时,须要使用托付。

C#中使用一个类时,分两个阶段。

首先须要定义这个类,即告诉编译器这个类由什么组成的。然后,实例化一个对象(除非仅仅使用静态方法)。

对于托付也是相似,也须要两个步骤。

首先必须定义要使用的托付。然后必须创建该托付的一个或多个实例。

定义语法:

  1. delegate void IntMethodInoker(int x);
  2. delegate double TwoLongsOp(long first, long second);
  3. delegate string GetString();

定义托付基本上是定义一个新类。所以能够在定义类的不论什么同样地方定义托付。即能够在还有一个类的内部定义,能够在不论什么类的外部定义,能够在名称空间中把托付定义为顶层对象。

依据托付定义的可见性,和托付的作用域,能够在托付的定义上应用随意常见的訪问修饰符:public、private、protected等

比如:

  1. public delegate string GetAString();

使用托付:

  1. private delegate string GetAString();
  2. static void Main()
  3. {
  4. int x=40;
  5. GetAString firstStringMethod = new GetAString(x.ToString);
  6. Console.WriteLine("String is {0}",firstStringMethod () );
  7. }

由上述代码能够看到。C#的托付在语法上总是接受一个參数的构造函数。这个參数就是托付引用的方法,可是这种方法必须匹配最初定义托付时的签名。

实际上。给托付实例提供圆括号与调用托付类的Invoke()方法全然同样。

使用Invoke完毕一个托付方法的封送。就相似于使用SendMessage方法来给界面线程发送消息,是一个同步方法。也就是说在Invoke封送的方法被运行完毕前,Invoke方法不会返回,从而调用者线程将被堵塞。

由于firstStringMethod 是一个托付类型的变量,所以C#编译器会用firstStringMethod.Invoke()取代firstStringMethod ()。

  1. firstStringMethod();
  2. firstStringMethod.Invoke();

为了降低输入量。仅仅须要托付实例,就能够仅仅传递地址的名称,即托付判断

  1. GetAString firstStringMethod = new GetAString(x.ToString);
  2. GetAString firstStringMethod = x.ToString;

注意:输入行事不能是x.ToString()。也不能把它传给托付变量。x.ToString表示把方法的地址赋予托付变量。

多播托付:

托付能够包括多个方法,这样的托付称为多播托付。假设调用多播托付。就能够按顺序连续调用多个方法。可是,托付的签名必须返回void。否则仅仅能得到托付调用的最后一个方法的结果。

多播托付演示样例程:

  1. delegate void Delegate_Multicast(int x, int y);
  2. Class Class2
  3. {
  4. static void Method1(int x, int y)
  5. {
  6. Console.WriteLine("You r in Method 1");
  7. }
  8. static void Method2(int x, int y)
  9. {
  10. Console.WriteLine("You r in Method 2");
  11. }
  12. public static void Main()
  13. {
  14. Delegate_Multicast func = new Delegate_Multicast(Method1);
  15. func += new Delegate_Multicast(Method2);
  16. func(1,2); // Method1 and Method2 are called
  17. func -= new Delegate_Multicast(Method1);
  18. func(2,3); // Only Method2 is called
  19. }
  20. }

解析:

上面的演示样例程序分别定义了名为method1 和 method2的两个接受整型參数、返回类型为void的方法。

在Main函数里使用以下的声明创建托付对象:

Delegate_Multicast func = new Delegate_Multicast(Method1);

然后使用+= 来加入托付,使用-=来移除托付。

合并托付:

托付对象的一个用途在于,能够使用 + 运算符将它们分配给一个要成为多路广播托付的托付实例。

组合的托付可调用组成它的那两个托付。

仅仅有同样类型的托付才干够组合。

- 运算符可用来从组合的托付移除组件托付。

  1. delegate void Del(string s);
  2. class TestClass
  3. {
  4. static void Hello(string s)
  5. {
  6. System.Console.WriteLine(" Hello, {0}!", s);
  7. }
  8. static void Goodbye(string s)
  9. {
  10. System.Console.WriteLine(" Goodbye, {0}!", s);
  11. }
  12. static void Main()
  13. {
  14. Del a, b, c, d;
  15. // Create the delegate object a that references
  16. // the method Hello:
  17. a = Hello;
  18. // Create the delegate object b that references
  19. // the method Goodbye:
  20. b = Goodbye;
  21. // The two delegates, a and b, are composed to form c:
  22. c = a + b;
  23. // Remove a from the composed delegate, leaving d,
  24. // which calls only the method Goodbye:
  25. d = c - a;
  26. System.Console.WriteLine("Invoking delegate a:");
  27. a("A");
  28. System.Console.WriteLine("Invoking delegate b:");
  29. b("B");
  30. System.Console.WriteLine("Invoking delegate c:");
  31. c("C");
  32. System.Console.WriteLine("Invoking delegate d:");
  33. d("D");
  34. }
  35. }
  36. /*-------------------------
  37. 输出
  38. Invoking delegate a:
  39. Hello, A!
  40. Invoking delegate b:
  41. Goodbye, B!
  42. Invoking delegate c:
  43. Hello, C!
  44. Goodbye, C!
  45. Invoking delegate d:
  46. Goodbye, D!
  47. ----------------------*/

匿名方法:

到眼下为止。要想使用托付工作。方法必须已经存在。可是还有还有一种使用托付的方法:即通过匿名方法。

匿名方法是用作托付的參数的一段代码。

用匿名方法定义托付的语法与前面的定义并没有差别。

但在实例化的时候就有了差别了。

假设使用匿名方法。则不必创建单独的方法,因此降低了实例化托付所需的编码系统开销。

比如。假设创建方法所需的系统开销是不必要的,在托付的位置指定代码块就非常实用。启动新线程即是一个非常好的演示样例。无需为托付创建很多其它方法,线程类就可以创建一个线程而且包括该线程运行的代码。

  1. void StartThread()
  2. {
  3. System.Threading.Thread t1 = new System.Threading.Thread
  4. (delegate()
  5. {
  6. System.Console.Write("Hello, ");
  7. System.Console.WriteLine("World!");
  8. });
  9. t1.Start();
  10. }

托付类型派生自 .NET Framework 中的 Delegate 类。

托付类型是封装的,它们不能派生出其它类,也不能从 Delegate 派生出自己定义类。 由于实例化的托付是一个对象。因此能够作为參数传递或分配给一个属性。 这同意方法作为參数接受托付并在稍后调用托付。

这被称为异步回调,是在长进程完毕时通知调用方的经常用法。 当以这样的方式使用托付时。使用托付的代码不须要知道要使用的实现方法。 功能相似于封装接口提供的功能。

浅析C#中的托付的更多相关文章

  1. 浅析Java中的final关键字

    浅析Java中的final关键字 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来 ...

  2. 浅析mongodb中group分组

    这篇文章主要介绍了浅析mongodb中group分组的实现方法及示例,非常的简单实用,有需要的小伙伴可以参考下. group做的聚合有些复杂.先选定分组所依据的键,此后MongoDB就会将集合依据选定 ...

  3. 浅析py-faster-rcnn中不同版本caffe的安装及其对应不同版本cudnn的解决方案

    浅析py-faster-rcnn中不同版本caffe的安装及其对应不同版本cudnn的解决方案 本文是截止目前为止最强攻略,按照本文方法基本可以无压力应对caffe和Ross B. Girshick的 ...

  4. 浅析JS中的模块规范(CommonJS,AMD,CMD)////////////////////////zzzzzz

    浅析JS中的模块规范(CommonJS,AMD,CMD)   如果你听过js模块化这个东西,那么你就应该听过或CommonJS或AMD甚至是CMD这些规范咯,我也听过,但之前也真的是听听而已.     ...

  5. 浅析Java中的访问权限控制

    浅析Java中的访问权限控制 今天我们来一起了解一下Java语言中的访问权限控制.在讨论访问权限控制之前,先来讨论一下为何需要访问权限控制.考虑两个场景: 场景1:工程师A编写了一个类ClassA,但 ...

  6. [转载]浅析Java中的final关键字

    浅析Java中的final关键字 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来 ...

  7. 浅析 JavaScript 中的 函数 currying 柯里化

    原文:浅析 JavaScript 中的 函数 currying 柯里化 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字 ...

  8. 浅析 JavaScript 中的 函数 uncurrying 反柯里化

    柯里化 柯里化又称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果. 因此柯里化的过程是 ...

  9. 【转】浅析Java中的final关键字

    谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法. ...

随机推荐

  1. Excel之定位和查找

    在数据量比较少的情况下,我们要到达Excel中某一位置时,通常会用鼠标拖动滚动条到达需要的位置,查找某已知固定的值,用Ctr+F,在查找内容中输入对应的值即可一个个的查找到其对应的位置.但当数据量较多 ...

  2. Linux 防火墙firewalld

    1.列出所有支持的 zone 和查看当前的默认 zone:[root@lxjtest ~]# systemctl start firewalld[root@lxjtest ~]# firewall-c ...

  3. boost asio异步读写网络聊天程序client 实例具体解释

    boost官方文档中聊天程序实例解说 数据包格式chat_message.hpp <pre name="code" class="cpp">< ...

  4. asp.net 如何配置authentication,完成基于表单的身份验证

    步骤一: 在根目录下的web.config中加入: <system.web> <authentication mode="Forms">           ...

  5. 回到顶部bug

    参考自一博客(https://www.cnblogs.com/abao0/p/6642288.html)内有慕课网教程(后发现有bug, 弃置不用了) 以下有问题, 当滚动条处于顶部时, 刷新页面, ...

  6. @Transient注解的使用

    转自:https://blog.csdn.net/sinat_29581293/article/details/51810805 java 的transient关键字的作用是需要实现Serilizab ...

  7. PHPNow升级PHP版本为5.3.5的方法(转)

    PHPNow升级PHP版本为5.3.5的方法 原文:http://sharebar.org/1142.html 在WIN上有时候需要测试一些PHP程序,又不会自行独立配置环境,那么PHPNow是非常好 ...

  8. OC中instancetype与id的区别

    1.在ARC环境下: instancetype用来在编译期确定实例的类型,而使用id的话,编译器不检查类型, 运行时检查类型. 2.在MRC环境下: instancetype和id一样,不做具体类型检 ...

  9. nginx配置文件结构,语法,配置命令解释

    摘要: nginx的配置文件类似于一门优雅的编程语言,弄懂了它的规范就可以自定义配置文件了,这个很重要~ 1,结构分析 nginx配置文件中主要包括六块:main,events,http,server ...

  10. [转]expect实现ssh自动交互

    shell脚本实现ssh自动登录远程服务器示例: #!/usr/bin/expect spawn ssh root@192.168.22.194 expect "*password:&quo ...