C#系列(2):其实委托很简单(下)

在上一篇博文中,我们知道了委托就是一种用来声明一个变量的数据类型,只不过委托声明的变量可以接受一个方法,只要方法签名保持一致就行了。

今天继续介绍委托。

(一)委托的本质就是class:

为什么说委托的本质就是class呢?我们知道当我们用C#编写完源代码后都要对项目进行编译,我们运行的C#代码实际上都是编译后的代码,编译后的代码我们成为:微软中间代码。

那我们就新建一个项目,在项目中只添加一个class,然后编写我们的C#源代码,然后接着就编译项目。让VS帮我们生成微软中间代码。

所以我们来看看编写一个class编译后的代码是什么样子,那就新建一个项目,里面添加一个Program.cs类文件,如下:

好了,接着在Program里写个Main方法,如下:

然后编译这个项目,让VS帮我们编译C#源代码,如下:

那我们编写的代码已经编译成功了,我们去项目所在文件夹里找到编译后的文件:

然后定位到debug文件夹里:

上图中,第一个文件就是我们编译后的文件:DemoForDelegate,编译后的文件名和我们新建的项目名称是一致的:DemoForDelegate。

那么现在得到了编译后的文件,这个就包含了我们编译后的中间代码了,所以我们现在需要查看这个文件里代码是什么样子,那就需要有一种相应的工具来查看。

这种工具就是:ILDasm,那我们去找我们电脑的系统盘里找到这个工具,因为我系统装在C盘,所以我去C盘把它找出来:

我找到了,它在这个目录下:C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools

然后双击打开它,如下:

所以呢,再把我们刚才编译后的项目托进去查看编译后的中间代码是什么样子:

之后:

我们看到编译后的文件里包含了项目:DemoForDelegate,这个项目唯一的Program类也包含进来了,所以和我们想象中差不多,该有的都有了。

同时,我们看在Program类下面还有.class private auto ansi beforefieldinit ,.ctor:void(),Main:void(string[])这3个成员,它们分别是:Program类,Program类的构造函数,Main方法。我们只要用鼠标双击这个3个成员就可以查看编译后的代码了,我们双击.ctor:void()看看:

那么到现在,我们已经知道如何查看C#编译后的代码了,接着回到委托。那么我们在Program类里添加一个委托吧:

再编译,然后再ILDasm里查看发生了什么:

从上图中我们可以看到委托最终也被编译成了一个同名的类,所以说委托的本质也是一个类。

(二)泛型委托:

一般在我们项目中会使用委托,所以我们来定义几个委托:

1 namespace DemoForDelegate
2 {
3     public delegate void delegateInt(int m);
4     public delegate void delegatedouble(double d);
5     public delegate void delegatestring(string str);
6     public delegate void delegatefloat(float f);
7     public delegate void delegatedecimal(decimal d);
8 }

我们定义了5个委托,这5个委托用于接受不同的方法。

但是,我们仔细找下规律就会发现其实这5个委托很相似:返回类型都是void,方法输入参数为1个。不同的是参数的数据类型。那么我想简化一下代码,想写一个通用的委托来取代上面那5个委托,既然它们的差异是参数的数据类型,那么很容易想到用泛型来让代码变得通用,如下:

 1 namespace DemoForDelegate
 2 {
 3     //public delegate void delegateInt(int m);
 4     //public delegate void delegatedouble(double d);
 5     //public delegate void delegatestring(string str);
 6     //public delegate void delegatefloat(float f);
 7     //public delegate void delegatedecimal(decimal d);
 8
 9     public delegate void MyAction<T>(T arg);
10 }

这样用一个委托就搞定了,所以在我们项目可以这样多定义一些这样的泛型委托:

1 namespace DemoForDelegate
2 {
3     public delegate void MyAction();
4     public delegate void MyAction<T>(T arg);
5     public delegate void MyAction<T1, T2>(T1 arg1, T2 arg2);
6     public delegate void MyAction<T1, T2, T3>(T1 arg1, T2 arg2,T3 arg3);
7     public delegate void MyAction<T1, T2, T3, T4>(T1 arg1, T2 arg2,T3 arg3,T4 arg4);
8     //more...
9 }

上面的委托都没有返回值,那我们再定义一些带返回值的委托吧:

 1 namespace DemoForDelegate
 2 {
 3     public delegate void MyAction();
 4     public delegate void MyAction<T>(T arg);
 5     public delegate void MyAction<T1, T2>(T1 arg1, T2 arg2);
 6     public delegate void MyAction<T1, T2, T3>(T1 arg1, T2 arg2,T3 arg3);
 7     public delegate void MyAction<T1, T2, T3, T4>(T1 arg1, T2 arg2,T3 arg3,T4 arg4);
 8     //more...
 9
10     //带返回值的委托
11     public delegate TResult MyFunc<out TResult>();
12     public delegate TResult MyFunc<out TResult,in T1>(T1 arg1);
13     public delegate TResult MyFunc<out TResult,in T1,in T2>(T1 arg1,T2 arg2);
14     public delegate TResult MyFunc<out TResult,in T1,in T2,in T3>(T1 arg1, T2 arg2,T3 arg3);
15     //more...
16
17 }

至于上面的委托名称取:MyAction,MyFunc,哈哈,不解释了,就一个名称而已,你懂。

如果大家有关C#技术方面更多的讨论可以加我的一个技术QQ群:240749438。

时间: 2024-10-13 00:05:05

C#系列(2):其实委托很简单(下)的相关文章

C#基础系列——委托实现简单设计模式

前言:上一篇介绍了下多线程的相关知识:C#基础系列--多线程的常见用法详解,里面就提到了委托变量.这篇简单介绍下委托的使用.当然啦,园子里面很多介绍委托的文章都会说道:委托和事件的概念就像一道坎,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里发慌.确实这东西就像最开始学C语言的指针一样,令人有一种很纠结的感觉,总觉得要调用一个方法直接调用就行了,为啥非要定义一个委托时执行这个方法呢.其实在C#里面很多的技术都是为了重用和简化代码而生,委托也不例外,很多使用C#多态去

轻松搞定Ajax(分享下自己封装ajax函数,其实Ajax使用很简单,难是难在你得到数据后来怎样去使用这些数据)

hey,guys!今天我们一起讨论下ajax吧!此文只适合有一定ajax基础,但还是模糊状态的同志,当然高手也可以略过~~~ 一.概念 Ajax(Asynchronous Javascript + XML(异步JavaScript和XML )) 二.效果 实现无刷新效果,向后台异步的取数据(不是只有AJAX才能实现这样的效果的哦,如img , script标签中的src属性也可以实现一样的效果,可以自己尝试一下哦) 三.本质 可能我们在学习过程中会觉得ajax好难,我也是这样过来的,我觉得是我们

[C# 网络编程系列]专题十:实现简单的邮件收发器

转自:http://www.cnblogs.com/zhili/archive/2012/09/24/2689892.html 引言: 在我们的平常工作中,邮件的发送和接收应该是我们经常要使用到的功能的.因此知道电子邮件的应用程序的原理也是非常有必要的,在这一个专题中将介绍电子邮件应用程序的原理.电子邮件应用程序中涉及的协议和实现一个简答的电子邮件收发器程序. 一.邮件应用程序基本知识 1.1 电子邮件原理及相关协议 说到电子邮件的原理,其实和我们现实生活中寄邮件和寄包裹是一样的原理的.就让我们

[转]大白话系列之C#委托与事件讲解(三)

本文转自:http://www.cnblogs.com/wudiwushen/archive/2010/04/21/1717378.html [我希望大家在看完文章的时候,多做做练习,自己也可以想个场景,动动手,这样才会有深刻的印象,不然遗忘的速度非常快] 今天我接着上面的3篇文章来讲一下,为什么我们在日常的编程活动中遇到这么多sender,EventArgs e 参数: protected void Page_Load(object sender, EventArgs e) { } prote

JavaScript进阶系列06,事件委托

在"JavaScript进阶系列05,事件的执行时机, 使用addEventListener为元素同时注册多个事件,事件参数"中已经有了一个跨浏览器的事件处理机制.现在需要使用这个事件处理机制为页面元素注册事件方法. □ 点击页面任何部分触发事件 创建一个script1.js文件. (function() { eventUtility.addEvent(document, "click", function(evt) { alert('hello'); }); }(

【转】《iOS7 by Tutorials》系列:iOS7的设计精髓(下)

四.聚焦于内容 在iOS7里,强调的不是眼花缭乱的装饰效果,而是最重要的内容本身. 下面我们来探讨这个主题: 1.删除不必要的内容 伟大的设计更多是减法和加法的组合. 虽然很酷的想法是很重要,但还有更重要的 ---- 杀死那些很酷的想法,以保持应用程序的重点. 1.1.不再强调chrome chrome是指您的应用里不是内容本身的一部分,如导航栏和标签栏. iOS 7非常不建议使用chrome,有些应用程序甚至会就干脆删除它.如果想要还原chrome的设计,请考虑以下几点: 1.1.1.chro

[iOS翻译]《iOS7 by Tutorials》系列:iOS7的设计精髓(下)

我们继续上篇的内容 四.聚焦于内容 在iOS7里,强调的不是眼花缭乱的装饰效果,而是最重要的内容本身. 下面我们来探讨这个主题: 1.删除不必要的内容 伟大的设计更多是减法和加法的组合. 虽然很酷的想法是很重要,但还有更重要的 ---- 杀死那些很酷的想法,以保持应用程序的重点. 1.1.不再强调chrome chrome是指您的应用里不是内容本身的一部分,如导航栏和标签栏. iOS 7非常不建议使用chrome,有些应用程序甚至会就干脆删除它.如果想要还原chrome的设计,请考虑以下几点:

自定义控件其实很简单7/12

尊重原创转载请注明:From AigeStudio(http://blog.csdn.net/aigestudio)Power by Aige 侵权必究! 炮兵镇楼 要在数量上统计中国菜的品种,在地域上毫无争议地划分菜系,在今天,是一件几乎不可能完成的事--Cut----抱歉--忘吃药了,再来一遍.如果非要对自定义控件的流程进行一个简单的划分,我会尝试将其分为三大部分:控件的绘制.控件的测量和控件的交互行为.前面我们用了六节的篇幅和一个翻页的例子来对控件的绘制有了一个全新的认识但是我们所做出的所

Https系列之一:https的简单介绍及SSL证书的生成

Https系列会在下面几篇文章中分别作介绍: 一:https的简单介绍及SSL证书的生成二:https的SSL证书在服务器端的部署,基于tomcat,spring boot三:让服务器同时支持http.https,基于spring boot四:https的SSL证书在Android端基于okhttp,Retrofit的使用 所有文章会优先在:微信公众号"颜家大少"中发布转载请标明出处 一:本文的主要内容介绍 https的介绍SSL证书的介绍自签名SSL证书介绍及生成方法CA证书介绍及申