关于C#中委托的一点理解

C#中委托是一种类型。可以这么笼统的理解:int型变量代表一个整型,而委托类型的变量代表一个方法的地址(将方法名称传入constructor并实例化该委托变量)。

--By Brisk Yu

 

1 为何要使用委托

我觉得网上关于什么现实生活的举例并不好,还是要从程序的本质去理解:

1)程序是由事件驱动的。

2)事件发生时,操作系统需要知道事件对应的处理函数。例如,用户按下鼠标时操作系统需要知道此时该做什么,是关闭窗口呢,还是打开某个文件呢?当网卡接收到数据包时操作系统也需要知道此时该做什么,是往上层传输呢,还是丢弃呢?

3)因此,我们需要将事件对应的处理函数提前告知操作系统(向操作系统注册),操作系统在发生该事件时,调用对应的处理函数,这便是回调,对应的处理函数也被称为回调函数

4)那么我们如何向操作系统注册回调函数呢(如何让操作系统知道发生对于事件它该干嘛呢)?对于C++,我们使用pointer,而对于C#,我们使用delegate。

 

2 如何使用委托

先从最基本的创建委托的方法开始,逐步变换为使用匿名方法和lambda expression。

1)最原始用法,用方法名初始化一个委托类型变量,调用该委托类型变量,执行承载的方法:

public delegate int SomeDelegate(int i);int SomeFunction1(int i) { Console.WriteLine("func1"+i);return 3; 
}。。。Main Function
{SomeDelegate sd = new SomeDelegate(SomeFunction1);sd(2);
}

 

2)如1)中,如果我们使用委托都需要定义一个委托类型比较麻烦,因此我们使用匿名委托:

删去1)中的

public delegate int SomeDelegate(int i);

并将main function中的代码改为:

Func<int, int> sd= new Func<int, int>(SomeFunction1);
sd(2);

Func和Action是C#为我们定义好了委托类型。Func指有返回参数的委托类型,其<>中最后一个参数既是返回参数的类型;Action指无返回参数的委托类型。

 

3)既然定义委托类型的代码可以拿掉,那么相应的方法声明与定义的语句也可以拿掉:

删去1)中的方法声明与定义的语句:

int SomeFunction1(int i) { Console.WriteLine("func1"+i);return 3; 
}

将main function 中的代码改为:

Func<int, int> sd = new Func<int, int>(delegate (int s) { Console.WriteLine("匿名方法" + s); return 88; 
});
int i = sd(2);

此时,Func()中的代码称为匿名方法,即没有方法名。

 

4)我们对3)中的代码进一步修改,将匿名方法改为lambda表达式。(lambda表达式是匿名方法的一种表示方法)

将mian function中的代码改为:

Func<int, int> sd = new Func<int, int>(s=> { Console.WriteLine("匿名方法"+s);return 88; 
});
int i = sd(2);

此时,对于lambda表达式,编译器会自动判断其类型,因此无需特指其类型。

 

3 实际应用

我们参考一下winform中鼠标点击事件响应是如何实现的

1)在System命名空间中定义一个委托类型

namespace System
{//// 摘要://     表示将用于处理不具有事件数据的事件的方法。//// 参数://   sender://     事件源。////   e://     不包含事件数据的对象。[ComVisible(true)]public delegate void EventHandler(object sender, EventArgs e);
}

2)在Control.cs(所有控件的父类)中定义一个EventHandler型的委托Click

public event EventHandler Click;

注:这里用到了event关键字,表明这个委托是一个事件。其实是指一簇委托。如果理解不了姑且将event拿掉来看。

 

3)编写鼠标点击事件响应代码

private void buttonStart_Click(object sender, EventArgs e)
{//TODO
}

 

4)用3)中方法实例化一个委托赋给Click

this.buttonStart.Click += new System.EventHandler(this.buttonStart_Click);

至此,程序便可以响应buttonStart这个按钮的响应事件了。更加具体的操作会深入到操作系统中,这里不再叙述。

--By Brisk Yu

转载于:https://www.cnblogs.com/brisk/p/10137719.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/395687.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里的事前验尸_(不太完全)100天的代码-验尸

阿里的事前验尸by JS由JS (不太完全)100天的代码-验尸 ((Not quite) 100 Days of Code — A Postmortem) At the end of last year, I wrote about my experience coding and making daily commits to GitHub for 30 consecutive days. I also pledged to keep the streak goi…

php超市管理系统论文,超市管理系统的设计与实现

当今社会为信息社会&#xff0c;世界已经进入在计算机信息管理领域中激烈竞争的时代。对于一般的商户而言&#xff0c;杂乱无章地陈放着的商品无疑会耗费他们大量的时间去对其整理并一一分类。他们需要更加便捷的手段去管理他们的商品以节约他们的时间成本以及人工成本。并且就…

只能输入正整数 以及常用的正则表达式

<input typetext idSYS_PAGE_JumpPage nameSYS_PAGE_JumpPage size3 maxlength5 οnkeyupthis.valuethis.value.replace(/[^1-9]/D*$/,"") οndragenter"return false" οnpaste"return !clipboardData.getData(text).match(//D/)"" sty…

jq 自动滑动轮换(向后插入小块)

// JavaScript Documentvar Marquee { arrIdObj : {/*marqueebox : {distance:-95,//移动距离delay:3000,//延迟时间speed:1000//移动时间},minCount:2 */}, //创建对象 startMarquee:function(){ //给参数赋值 if(this.arrIdObj ! null && typeof this.arrIdObj &qu…

bzoj 2178 圆的面积并 —— 辛普森积分

题目&#xff1a;https://www.lydsy.com/JudgeOnline/problem.php?id2178 先看到这篇博客&#xff1a;https://www.cnblogs.com/heisenberg-/p/6740654.html 好像本应算弓形面积、三角形面积之类的&#xff0c;但不会...于是用辛普森积分硬做... 参考了这篇博客&#xff1a;ht…

php获取访问者ip地址汇总,php获取访问者IP地址汇总_PHP

//方法1&#xff1a;$ip $_SERVER["REMOTE_ADDR"];echo $ip;//方法2&#xff1a;代码如下:$user_IP ($_SERVER["HTTP_VIA"]) ? $_SERVER["HTTP_X_FORWARDED_FOR"] : $_SERVER["REMOTE_ADDR"];$user_IP ($user_IP) ? $user_IP : $…

Charles抓包工具的使用

2019独角兽企业重金招聘Python工程师标准>>> 感谢唐巧分享的文章&#xff0c;受益匪浅 文章目录 1. 目录及更新说明2. Charles 限时优惠3. 简介4. 安装 Charles5. 将 Charles 设置成系统代理6. Charles 主界面介绍7. 过滤网络请求8. 截取 iPhone 上的网络封包 8.1. …

python每秒20个请求_使用Python每秒百万个请求

python每秒20个请求by Paweł Piotr Przeradowski通过PawełPiotr Przeradowski 使用Python每秒百万个请求 (A million requests per second with Python) Is it possible to hit a million requests per second with Python? Probably not until recently.使用Python每秒可以…

iOS开发——处理1000张图片的内存优化

一、项目需求 在实际项目中&#xff0c;用户在上传图片时&#xff0c;有时会一次性上传大量的图片。在上传图片前&#xff0c;我们要进行一系列操作&#xff0c;比如&#xff1a;旋转图片为正确方向&#xff0c;压缩图片等&#xff0c;这些操作需要将图片加载到内存中&#xff…

jquery ui php,php – 打开带有动态内容的jQuery UI对话框

我有一个关于jQuery UI对话框的问题,并显示数据库中的动态内容.所以我得到了一个web应用程序,我还需要创建一个管理模块来管理所有用户和其他信息.我创建了一个页面,显示列表中的所有用户,在每一行中我也创建了一个编辑按钮.我想这样做,当你按下用户的编辑按钮时,会打开一个对话…

linux shell的单行多行注释

1.单行注释&#xff0c;使用符号# echo "123456"echo "test"#echo "comment“ 2. 多行注释 &#xff08;1&#xff09;使用 :<<! &#xff01; filenametest.txt :<<! fileContentcat $filenamei0 for line in $fileContent dofileList[…

MapReduce Input Split 输入分/切片

MapReduce Input Split&#xff08;输入分/切片&#xff09;详解 public static long getMaxSplitSize(JobContext context) { return context.getConfiguration().getLong(SPLIT_MAXSIZE, Long.MAX_VALUE); } 如果没有设置这maxsize默认是Long.MAX_VALUE public static long …

win7无损扩大c盘空间_无损网络导航的空间模型

win7无损扩大c盘空间by Patryk Adaś通过PatrykAdaś 无损网络导航的空间模型 (A Spacial Model for Lossless Web Navigation) In my last post I described the concept of navigation trails as an evolution of the standard tabbed browsing model.在我的上一篇文章中&am…

php访问者信息,如何通过PHP检索访问者的ISP?

我试图纠正拉姆库马尔的答案,但每当我编辑他们的帖子,我将被暂时禁止,我的修改被忽略。(至于为什么,我不知道,这是我第一次也是唯一一次在这个网站上编辑。)由于网站更改和管理员执行基本的bot检查(检查标题),他的代码不再工作:$IP $_SERVER[REMOTE_ADDR];$User_Agent Mozill…

从《在小吃店遇见凯恩斯》初识经济

最近在看《在小吃店遇见凯恩斯》这本书&#xff0c;算是对经济和经济学的初步认识。 那些概念 1. 经济与经济学 经济&#xff1a;经世济民&#xff0c;经营国家、救赎百姓&#xff0c;发展国家经济进步、促成人人致富。 经济学&#xff1a;研究发展国家经济进步、促成人人致富的…

2pc 3pc_在1990年代如何宣传PC

2pc 3pcby Ilya Pestov通过伊利亚佩斯托夫(Ilya Pestov) 在1990年代如何宣传PC (How PCs were advertised in the 1990s) Today, hard drives are boring. You can buy a terabyte hard drive for $50. But back in the day, people would get excited when they saw ads anno…

WPF自定义空心文字

WPF自定义空心文字 原文:WPF自定义空心文字首先创建一个自定义控件&#xff0c;继承自FrameworkElement&#xff0c;“Generic.xaml”中可以不添加样式。 要自定义空心文字&#xff0c;要用到绘制格式化文本FormattedText类。FormattedText对象提供的文本格式设置功能比WPF提供…

php默认日志位置,Laravel 修改默认日志文件名称和位置的例子

修改默认日志位置我们平常的开发中可能一直把laravel的日志文件放在默认位置不会有什么影响&#xff0c;但如果我们的项目上线时是全量部署&#xff0c;每次部署都是git中最新的代码&#xff0c;那这个时候每次都会清空我们的日志&#xff0c;显示这不是我们所期望的&#xff0…

【转】UITableView详解(UITableViewCell

原文网址&#xff1a;http://www.kancloud.cn/digest/ios-1/107420 上一节中,我们定义的cell比较单一,只是单调的输入文本和插入图片,但是在实际开发中,有的cell上面有按钮,有的cell上面有滑动控件,有的cell上面有开关选项等等,具体参加下面2个图的对比: 我们可以通过…

Android 最简单的MVP案例;

随手撸个发出来&#xff1a; V&#xff1a;界面层 //界面层需要实现P.View方法&#xff0c;然后重写P.View中的方法&#xff1b;M层给的数据就在这些个方法的参数中&#xff1b; // 还要获取到P.Provide的实例&#xff0c;使用P.Provide去调用M层的方法&#xff1b; public cla…