委托、Lambda和事件
委托
委托相当于C语言当中的函数指针,不过委托是类型安全的类,它定义了返回类型和参数的类型。
声明委托
在C#中使用一个类,分为两个阶段。首先,需要定义这个类,告诉编译器这个类由什么字段和方法组成,然后实例化这个类的一个对象。使用委托也要经过这两个步骤。首先,定义要使用的委托(类),告诉编译器这委托(类)表示的是哪种类型的方法,然后创建委托的实例。它们都是要即先声明,再实例化。只是有点不同,类在实例化之后叫对象或实例,但委托在实例化后仍叫委托。
//定义IntMethodInvoker委托类
delegate void IntMethodInvoker(int x);
static void Main(string[] args)
{
//创建IntMethodInvoker委托实例,并把Method1方法委托给invoker
IntMethodInvoker invoker = new IntMethodInvoker(Method1);
invoker();
} static void Method1(int i)
{
Console.Write(i);
}
定义委托类似于方法的定义,但没有方法体,定义的前面要加关键字delegate。委托相当类,所以可以在定义类的任何地方定义委托,也就是说可以在类外部,也可以在类内部定义,当然也可以在委托定义上使用任意的访问修饰符。定义委托类型时就指明了该委托类型的实例所能接受的方法的返回类型和其参数。例如上例中的IntMethodInvoker委托类的实例就只能接受只有一个int参数及返回为空的方法。执行委托实例跟执行方法一样,直接在委托实例后加括号,并在括号中填入该委托所对应参数。
实际上,给委托实例提供圆括号与调用委托类的hvoke()方法完全相同,C#编译器会用invoke.invoke(3)代替invoker(3)。
上面声明实例对象时,也可以简写为下面方式,注意Method1后面没有括号。
IntMethodInvoker invoker =Method1
给定委托的实例可以作用任何类型的任何对象的实例方法或静态方法,只要方法的签名匹配于委托的签名即可。
Action(T)和Func(T)委托
除了我们自己定义委托类型,微软的类库中也为我们内置Action<T>和Func<T>的泛型委托,这样就可以免得我们自己去定义委托类型了,我们可以直接使用内置的委托类型。
泛型Action<T>委托表示引用一个void返回类型的方法,该委托内存在不同的变体,它最多可传递16 个参数。非泛型Action委托类型可以调用带无返回类型且无参数的方法。
Func<T>委托类似于Action<T>委托,不同的是Func<T>调用的是带有返回类型的方法。Func<T>也定义了不同的变体,它最多可以传递16个参数和一个返回类型。Func<out TResult>委托类型可以调用带返回类型且无参数的方法。
匿名方法
最直接的理解就没有名称的方法,例如我们给最上面的例子中的IntMethodInvoker委托实例invoker委托一个方法,我们可以像下面一样写,这样我们就不用另外去定义一个方法了。
invoker = delegate(int param)
{
Console.Write(param);
};
如果委托类型是定义有返回类型的话,就直接在匿名方法体最后返回指定类型的值就可以了。
Lambda表达式
上面使用用匿名方法的例子可以改为使用Lambda表达式:
invoker = param =>
{
Console.Write(param);
};
lambda运算符"=>"的左边列出了需要的参数,lambda运算符右边则写方法的实现代码。
如果lambda表达式只有一个参数,就直接写参数名就可以了,如上例。如果有多个参数则用括号括起来,每个参数之间用逗号隔开。当然在每个参数前面我们可以为参数添加类型:
invoker =(string param )=>
{
Console.Write(param);
};
事件
事件是基于委托的,为委托提供了一种发布/订阅机制。
delegate void Mydelegate(int a);
event Mydelegate MyEvent;
声明事件使用关键字event。上面我们只用一行就定义了一个事件,其实这只是C#的一个语法糖。这非常类似于自动属性和完整属性之间的关系。对于事件,使用add和remove关键字添加和删除委托的处理程序:
private Mydelegate myEvent;
public event Mydelegate MyEvent
{
add
{
this.myEvent= (Mydelegate)Delegate.Combine(this.myEvent, value);
}
remove
{
this.myEvent= (Mydelegate) Delegate.Remove(this.myEvent, value);
}
}
事件其实就是在内部把一个委托实例封装起来,向外只提供注册和注销方法。
委托、Lambda和事件的更多相关文章
- 委托/lambda表达式/事件
委托 委托是执行安全的类,它的使用方式与类类似(即都需要定义再实例化),不同在于,类在实例化之后叫对象或类的实例,但委托在实例化后仍叫委托,委托可以把函数作为参数传递. 语法声明: delegate ...
- 委托+内置委托方法+多播委托+lambda表达式+事件
委托概念:如果我们要把方法当做参数来传递的话,就要用到委托.简单来说委托是一个类型,这个类型可以赋值一个方法的引用. 声明委托: 在C#中使用一个类分两个阶段,首选定义这个类,告诉编译器这个类由什么字 ...
- 委托-异步调用-泛型委托-匿名方法-Lambda表达式-事件【转】
1. 委托 From: http://www.cnblogs.com/daxnet/archive/2008/11/08/1687014.html 类是对象的抽象,而委托则可以看成是函数的抽象.一个委 ...
- C# Note2:委托(delegate) & Lambda表达式 & 事件(event)
前言 本文主要讲述委托和Lambda表达式的基础知识,以及如何通过Lambda表达式实现委托调用,并阐述.NET如何将委托用作实现事件的方式. 参考:C#高级编程 1.什么是委托(delegate)? ...
- .NET进阶篇-语言章-2-Delegate委托、Event事件
知识只有经过整理才能形成技能 整个章节分布简介请查看第一篇 内容目录 一.概述 二.解析委托知识点 1.委托本质 2.委托的使用 3.委托意义 逻辑解耦,减少重复代码 代码封装支持扩展 匿名方法和La ...
- javascript事件委托和jQuery事件绑定on、off 和one
一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...
- javascript 事件委托 和jQuery事件绑定on、off 和one
一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...
- 整理之DOM事件阶段、冒泡与捕获、事件委托、ie事件和dom模型事件、鼠标事件
整理之DOM事件阶段 本文主要解决的问题: 事件流 DOM事件流的三个阶段 先理解流的概念 在现今的JavaScript中随处可见.比如说React中的单向数据流,Node中的流,又或是今天本文所讲的 ...
- 关于C# 委托(delegate)与事件(event)的用法及事例
C#中的委托和事件对于新手可能会有一点难理解,所以先从一个小例子入手,以便能更好的理解其如何使用.有一个学生每天定闹钟在早上6点起床,所以当每天早上6点的时候,闹钟就会响起来,从而学生才会按时起床. ...
- js事件委托和jQuery事件绑定on , off , one , bind , unbind , die
一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...
随机推荐
- tar打包过滤某个文件及文件夹
ip=ip add|grep eth0|grep -i inet|awk '{print $2}'|cut -d '/' -f 1 cd /data tar -zvcf `echo $ip`_`dat ...
- N-Queens And N-Queens II [LeetCode] + Generate Parentheses[LeetCode] + 回溯法
回溯法 百度百科:回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步又一次选择,这样的走不通就退回再走的技术为回溯法 ...
- MFC自绘(17篇)
http://www.cnblogs.com/lidabo/category/477377.html
- OpenStreetMap初探(一)——了解OpenStreetMap
1. 開始关注OpenStreetMap始于此博文:<微软对抗谷歌的秘密武器:开源地图OpenStreetMap> http://news.csdn.net/a/20120328/313 ...
- uploadify,实际开发案例【选择完文件点击上传才上传】
<script type="text/javascript"> )+Math.floor(Math.random()*)+']-'; //设置随机文件前缀. $k(fu ...
- 设计模式(三)-- 适配器模式(Adapter)
适配器模式(Adapter) 考虑一个记录日志的应用,由于用户对日志记录的要求很高,使得开发人员不能简单地采用一些已有的日志工具或日志框架来满足用户的要求,而需要按照用户的要求重新开发新的日志管理系统 ...
- Android学习4、Android该Adapter
一.Adapter介绍 An Adapter object acts as a bridge between an AdapterView and the underlying data for th ...
- Delphi回调函数及其使用
Delphi回调函数及其使用 1 回调函数的概述 回调函数是这样一种机制:调用者在初始化一个对象(这里的对象是泛指,包括OOP中的对象.全局函数等)时,将一些参数传递给对象,同时将一个调用者可以访问的 ...
- html中的rowspan和colspan
摘自w3school(http://www.w3school.com.cn/tags/att_td_colspan.asp)colspan 属性规定单元格可横跨的列数.<table border ...
- 为什么Lisp语言如此先进?(译文) - 阮一峰的网络日志
为什么Lisp语言如此先进?(译文) - 阮一峰的网络日志 为什么Lisp语言如此先进?(译文)