委托

  委托相当于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. js点击button按钮跳转到另一个新页面

    点击按钮怎么跳转到另外一个页面呢?我们在网站制作中可能是需要的,因为有时我们需要做这样的效果,尤其是将按钮做成一个图片,而点击图片要跳转到新的页面时,怎么做到呢? 这样的效果可以:onclick=&q ...

  2. 1.0.2-学习Opencv与MFC混合编程之---为播放AVI视频添加滑动条

    源代码地址:http://download.csdn.net/detail/nuptboyzhb/3961642 版本1.0.2新增内容 Ø  全局变量和函数的添加: 在CVMFCview.cpp文件 ...

  3. ajax里面同步和异步的区别

    同步:js等ajax完成后才继续执行 异步:js不等ajax完成直接执行 这种区别最明显是在ajax在循环里面的时候,如果你的ajax里面的参数跟循环的条件有关,你会发现参数会出现错误,因为异步的话, ...

  4. Android手机怎样录制屏幕及转GIF

    有时候我们须要录制Android 手机的屏幕,比方写了一个Demo应用,须要公布到博客和微博上. 例如以下是我录制转GIF的效果图 对于Android4.4的上的手机,系统自带了一个命令screenr ...

  5. 自己总结的ruby on rails 查询方法

    闲来无事,结合以前的代码,总结了ruby on rails的查询方法,方便自己以后查看,也方便后来人,如下,欢迎批评指正 1::simpleDB modules = find(:all, :condi ...

  6. 基于visual Studio2013解决面试题之0403串联字符串

     题目

  7. cp命令的实现

    #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #define BUFFERSIZE 4096 ...

  8. clear、REFRESH、free区别

    clear可以清楚一个工作区或变量.但是如果该内表是带表头的,清空内表时需要在该内表后加[].例如:clear gt_tab[]. free可以清空带表头的内表但是不会清空这个带表头内表的表头,但是也 ...

  9. iOS UIScrollView 停止滑动 减速

    1.UIScrollView 减速 可能通过decelerationRate的属性来设置,它的值域是(0.0,1.0),当decelerationRate设置为0.1时,当手指touch up时就会很 ...

  10. [UVALive 6663 Count the Regions] (dfs + 离散化)

    链接:https://icpcarchive.ecs.baylor.edu/index.php? option=com_onlinejudge&Itemid=8&page=show_p ...