c#委托的理解,c#委托的本质是什么

  c#委托的理解,c#委托的本质是什么

  试想一下,如果我们为烹饪写一个厨师的烹饪方法,包括取菜、切菜、配菜、烹饪四个步骤,但是写这个方法代码的人希望配菜由方法的调用者来实现。换句话说,他希望在调用方法时将代码作为参数接收,并在方法中执行传入的代码。

  但是,如何为一个方法传入代码呢?当然,大家都想到了通过接口的方式来实现。先不讨论接口,因为微软已经给我们提供了一个叫[delegate]的类型。

  (1)委托依据:

  1.先看代码:

  (1).设置一个方法:void say hi(string name){ console . writeline(" hi ~ " name "!");}

  (2).声明一种委托类型:Delegate Void DGSayhi(String Uname);

  (3).创建委托类型对象:DGSayHi DG obj=new DGSayHi(SayHi);//方法在构造函数中传递

  (4).委托的执行:

  DG obj(" James Zou ");

  //调用委托(奇怪:括号内调用对象?稍后解释。)

  输出:Hi~JamesZou!

  2.什么是委托?

  (1)概念:“C#

  中的委托类似于C或C。

  函数指针在。使用委托允许程序员在委托对象中封装方法引用。那么调用delegate对象就可以执行delegate对象中方法引用所指向的方法,而不需要知道编译时会调用哪个方法(比如参数为delegate type的方法,它提供了一种机制来指定程序回调的方法)。" -

  引自MSDN

  (2) Popular:是一个调用列表,可以存储很多方法的指针(但是方法签名必须和委托类型签名相同)。只要调用这个列表,列表中所有指针对应的方法就会依次执行。

  (3)举个例子:有A、C、d三台机器,点击一个红色按钮,它就会运行。操作员接到电话后被指示打开广告机,然后工作人员在接到电话后打开广告机。(在本例中

  三机是方法,操作员可视为“委托”)

  (4)轮廓图例:

  DGSayHi dgObj=new

  DGSayHi(萨伊希);

  dgObj("詹姆斯");

  //调用委托对象时,会执行委托对象中的方法。

  3.委托有什么用?

  A.可以帮助程序员在需要的时候根据条件动态执行多个方法:(前面例子的代码)

  (1)设置三种方法:

  void SayHi(字符串

  名称){控制台。WriteLine("嗨~ "名);}

  空的

  大昭湖(串名){

  控制台。WriteLine("你好~ "名);}

  线

  OHaUo(字符串名){ Console。WriteLine(" oh ahuo ~ "

  姓名);返回“JapHi”;}

  (2)创建委托类型对象,并通过向构造函数传递参数来向委托对象“注册”第一个方法:

  DGSayHi dgObj=new

  DGSayHi(萨伊希);

  (3)继续“注册两种方法”:

  dgObj

  =大昭湖;//(奇怪:对象是用=符号操作的?稍后解释)

  //dgObj

  =oh ahuo;//注释这一行代码,因为编译时报错,OhaUo方法的签名和委托类型的签名不一致(委托签名没有返回值)。

  (4)执行委托对象:

  dgObj("詹姆斯");//执行了在此委托中注册的两个方法。

  输出:

  嗨~詹姆斯

  你好~詹姆斯

  (5)轮廓图例

  作为委托方法参数(回调方法机制)

  (1).连接上一个示例中的代码,然后定义一个方法:

  void DoTestDelegateFun(DGSayHi

  DgObj){dgObj(“钢铁侠”);}

  (2).调用此方法:

  DoTestDelegateFun(say hi);//Output: Hi~钢铁侠(奇怪:居然直接传方法?稍后解释)

  C.委托语法糖

  (1).注意,上面有3个地方我们都觉得“奇怪”:

  A.调用委托对象DG obj(“James Zou”);

  B.向委员会登记方法

  dgObj=大昭湖;

  c .将方法作为参数

  DoTestDelegateFun(say hi);

  这些用法实际上是FW提供的简单语法(它们有一个可爱的名字:syntax sugar),在编译时被编译器转换成完整的代码:

  a.

  dgObj。invoke(" JamesZou ");

  b.dgObj=(DGSayHi)

  委派。Combine(dgObj,new DGSayHi(这个。大昭湖));

  //Combine方法将第二个参数添加到dgObj,并返回委托对象。

  c.这个。DoTestDelegateFun(新DGSayHi(这个。say hi));

  委托类、调用方法、组合方法从何而来?

  (2)委托原则

  1.delegate关键字

  (1).概念:delegate关键字用于声明引用类型,引用类型可用于封装命名方法或匿名方法。

  (2)编译后生成的中间代码。

  请考虑一下。关键字是类型吗?没有,编译器遇到这个关键字做了什么?在[IL反汇编器]的帮助下,我们来看看:

  A.开始-程序-如图所示:

  B.打开项目文件夹下的bin\Debug文件夹,并找到该程序集。

  CodeForFun.exe,拖动到【IL反汇编器】界面,可以看到汇编的IL代码:

  我们找到了定义委托DGSayHi的DelegateForFun类,并在其中找到了委托类型声明代码。

  编译前:delegatestringgsayhi(string

  uName);

  进入一个班级:

  点开之后我们来看看:

  你看到了什么?

  (一)。继承了系统。中多重委托

  。包含构造方法、BeginInvoke、EndInvoke和Invoke方法。

  也就是说,此时,委托代码已经编译成如下代码:

  编译后:

  classDGSayHi:系统。中多重委托

  {

  公众的

  DelegateForFun();

  void Invoke(字符串值);

  IAsyncResult BeginInvoke(字符串值,AsyncCallback回调,对象

  对象);

  void EndInvoke(IAsyncResult结果);

  (3)系统。多播委托类

  让我们借助来看看类库中的MulticastDelegate类。网络反射器工具。

  public abstract class multicast Delegate:委托

  由此可以看出继承关系:DGSayHi

  组播代表代表

  MulticastDelegate类中有三个重要成员,其中两个继承自

  委托人:

  A.三者的作用:

  方法指针存储在_methodPtr中。

  _target用于保存方法所在的对象。

  _invocationList在使用时实际上是一个对象数组。当注册多个方法时,其他方法保存在该成员中,它也是委托链的关键容器。

  B.外形图:

  图中的委托对象dgObj在创建时会创建一个指向方法。

  SayHi的指针并保存在_methodPtr中;_target持有SayHi方法所在类的对象(比如我在表单中按钮的click方法中写了这段代码,那么此时

  _target是SayHi方法所在的form对象);_invocationList保存指向另外两个方法的指针,但是这两个方法指针安装在

  在MuticastDelegate对象中。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • 设计一个简单的C#控制台应用程序,C#控制台程序,C# 创建控制台应用程序
  • 深入解析windows第8版,深入解析C#(第4版)
  • 数组代码,c# 数组操作,C# 数组实例介绍(图文)
  • 学会C#要多久,学会c#要多久,c#学习之30分钟学会XAML
  • 回溯法01背包问题c,回溯法求解01背包问题伪代码,C#使用回溯法解决背包问题实例分析
  • xml文件转义字符,xml转意字符,C# XML中的转义字符操作
  • winform 进度条控件,c# 进度条使用
  • winform 进度条控件,c# 进度条使用,C#使用winform实现进度条效果
  • winform backgroundworker,c# isbackground
  • winform backgroundworker,c# isbackground,C# BackgroundWorker用法详解
  • lua与c#交互,lua c#
  • lua与c#交互,lua c#,ToLua框架下C#与Lua代码的互调操作
  • linq c#,linq原理 c#
  • linq c#,linq原理 c#,c#中LINQ的基本用法实例
  • java decimal保留两位小数,sql中decimal函数保留2位小数,C#中decimal保留2位有效小数的实现方法
  • 留言与评论(共有 条评论)
       
    验证码: