委托

  委托相当于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和事件的更多相关文章

  1. 委托/lambda表达式/事件

    委托 委托是执行安全的类,它的使用方式与类类似(即都需要定义再实例化),不同在于,类在实例化之后叫对象或类的实例,但委托在实例化后仍叫委托,委托可以把函数作为参数传递. 语法声明: delegate ...

  2. 委托+内置委托方法+多播委托+lambda表达式+事件

    委托概念:如果我们要把方法当做参数来传递的话,就要用到委托.简单来说委托是一个类型,这个类型可以赋值一个方法的引用. 声明委托: 在C#中使用一个类分两个阶段,首选定义这个类,告诉编译器这个类由什么字 ...

  3. 委托-异步调用-泛型委托-匿名方法-Lambda表达式-事件【转】

    1. 委托 From: http://www.cnblogs.com/daxnet/archive/2008/11/08/1687014.html 类是对象的抽象,而委托则可以看成是函数的抽象.一个委 ...

  4. C# Note2:委托(delegate) & Lambda表达式 & 事件(event)

    前言 本文主要讲述委托和Lambda表达式的基础知识,以及如何通过Lambda表达式实现委托调用,并阐述.NET如何将委托用作实现事件的方式. 参考:C#高级编程 1.什么是委托(delegate)? ...

  5. .NET进阶篇-语言章-2-Delegate委托、Event事件

    知识只有经过整理才能形成技能 整个章节分布简介请查看第一篇 内容目录 一.概述 二.解析委托知识点 1.委托本质 2.委托的使用 3.委托意义 逻辑解耦,减少重复代码 代码封装支持扩展 匿名方法和La ...

  6. javascript事件委托和jQuery事件绑定on、off 和one

    一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...

  7. javascript 事件委托 和jQuery事件绑定on、off 和one

    一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...

  8. 整理之DOM事件阶段、冒泡与捕获、事件委托、ie事件和dom模型事件、鼠标事件

    整理之DOM事件阶段 本文主要解决的问题: 事件流 DOM事件流的三个阶段 先理解流的概念 在现今的JavaScript中随处可见.比如说React中的单向数据流,Node中的流,又或是今天本文所讲的 ...

  9. 关于C# 委托(delegate)与事件(event)的用法及事例

    C#中的委托和事件对于新手可能会有一点难理解,所以先从一个小例子入手,以便能更好的理解其如何使用.有一个学生每天定闹钟在早上6点起床,所以当每天早上6点的时候,闹钟就会响起来,从而学生才会按时起床. ...

  10. js事件委托和jQuery事件绑定on , off , one , bind , unbind , die

    一. 事件委托什么是事件委托?用现实中的理解就是:有100 个学生同时在某天中午收到快递,但这100 个学生不可能同时站在学校门口等,那么都会委托门卫去收取,然后再逐个交给学生.而在jQuery 中, ...

随机推荐

  1. 深入浅出Hadoop实战开发(HDFS实战图片、MapReduce、HBase实战微博、Hive应用)

    Hadoop是什么,为什么要学习Hadoop?     Hadoop是一个分布式系统基础架构,由Apache基金会开发.用户可以在不了解分布式底层细节的情况下,开发分布式程序.充分利用集群的威力高速运 ...

  2. 基于visual Studio2013解决C语言竞赛题之1052求根

       题目 解决代码及点评 /* 功能:用简单迭代法解方程 e^x - x - 2 = 0 它有两个根(如图),其迭代公式为: 1) x[n+1]= e^x*n-2 (初值X<0时) ...

  3. PB+MS SQL+触发器必须指出

    PB+MS SQL+触发器必须指出: 若触发器存在两笔以上的返回值,比方两条update 语句,被误判为数据有改变.存盘不成功. 提示: Row changed between retrieve an ...

  4. VS2010(2012)中使用Unit Testing进行单元测试

    原文 VS2010(2012)中使用Unit Testing进行单元测试 使用VS 2012自带的Unit Testing工具进行单元测试是非常方便的.网上关于这方面的例子很多,这篇随笔只起个人学习笔 ...

  5. Thymeleaf模板的使用

    使用模板的要点:     页面主体结构固定,具体参数可变,尽可能让参数动态化,才能提高模板的复用性 ================================================== ...

  6. ADS1.2安装

    一.ADS1.2的安装 1. 解压 2. 双击打开ads1.2 3.我们选择当中的SETUP.EXE文件,进行安装 4.点击Next: 5.这是许可文件,假设允许的话选择Yes: 6.选择安装文件夹, ...

  7. android端从服务器抓取的几种常见的数据的处理方式

    1.图片 public void look(View v) { String path = et_path.getText().toString(); try { URL url = new URL( ...

  8. Linux红黑树(二)——访问节点

    核心对红黑树使用两点说明 1.头文件 <Documentation/rbtree.txt> Linux's rbtree implementation lives in the file ...

  9. 设置程序版本等信息(可直接修改pro文件设置,但是更推荐使用rc文件设置)

    Qt版本:5.2.0 在.pro文件中设置版本等信息 VERSION = 1.2.3 QMAKE_TARGET_PRODUCT = 产品名称QMAKE_TARGET_COMPANY = 公司QMAKE ...

  10. chfn,chsh,last,login,mail ,mesg ,talk,wall,write,nice ,pstree ,renice,skill ,expr ,reset,tset,compress ,lpd ,lpq ,lpr ,lprm,fdformat ,mformat ,mkdosf

    名称:chfn 使用权限:所有使用者 用法:shell>> chfn 说明:提供使用者更改个人资讯,用于finger and mail username 范例: shell>> ...