c#中如何深入理解“事件与委托”

c#中如何深入理解“事件与委托”
c#中如何深入理解“事件与委托”

C#中如何深入理解“事件与委托”?(初学者必看)

2008年01月19日星期六 22:57

事件与委托似乎很难以理解,这是因为它们的使用方式与常用的编码有很大的差别,例如通常编写的都是同步代码,调用一个类型的方法,会即刻出现方法执行的结果,这是符合逻辑的。但在某些情况中,同步代码未必满足需求,拿公共汽车来打个比方,如果交通管制中心希望每一辆公车到达一个站点时都发送给自己一个信号以便自己能够随时掌握交通状况,使用同步代码,公汽对象肯定需要调用管制中心对象,这样就出现了我们一直不愿意看到的情况:两个类型紧密地耦合在一起。既然要其它类型对自己的行为作出反应,亲自调用其类型的方法似乎不可避免,在同步代码中,很难避免这种紧密的类型调用关系。

另一个差别是在一般情况下,我们只将属性作为参数传递给方法,而很少会考虑将一个方法传递给另一个方法。

我们抛弃各种C#参考书中桀骜难懂的事件与委托概念,设想一个情景来理解事件与委托的使用:有一家IT公司,董事长不希望自己的雇员在上班时间玩游戏,但又不可能每时每刻都盯着每个雇员,因此,他希望使用一种新的方式实现监视雇员的效果:如果有雇员违反规定,某个设备或专门的监查人员将自动发出一个消息通知他,董事长只需要在事情发生时进行处理。

因此,这个用例实际上是两种类型——董事长类与雇员类——之间的交互,下面的代码将给读者展示如何使用委托与事件机制实现这种交互:

首先,我们需要在董事长类与雇员类之间定义一个委托类型,用于传递两者之间的事件,这个类型就是一个监视设备或专门负责打小报告的监查人员:

public delegate void DelegateClassHandle();

定义一个委托的过程类似方法的定义,但它没有方法体。定义委托一定要添加关键字delegate。由于定义委托实际上相当一个类,因此可以在定义类的任何地方定义委托。另外,根据委托的可见性,也可以添加一般的访问修饰符,如public、private和protected。

委托的返回值类型为void,这并非表示委托类型本身带有返回值,该返回值类型是指委托的目标函数类型,即它委托的一个事件处理函数返回值是void类型。

新建一个雇员类Employee,其代码如下:

public class Employee

{

public event DelegateClassHandle PlayGame;

public void Games()

{

if (PlayGame != null)

{

PlayGame();

}

}

}

雇员类Employee代码中定义了一个DelegateClassHandle类型的事件PlayGame,它的定义方式也很特殊,首先必须使用关键字event,表示PlayGame是一个事件,同时还必须声明该事件的委托类型为DelegateClassHandle,即将来由该类型的委托对象负责通知事件。

如果有雇员开始玩游戏,它将执行Games方法,而只要该方法一被调用,就会触发一个事件PlayGame,然后董事长就会收到这个事件的消息——有人在玩游戏了。

董事长类代码如下,他有一个方法Notify用于接收消息:

public class Admin

{

public void Notify()

{

System.Console.WriteLine("someone is playing game");

}

}

Employee的PlayGame事件如何与Admin的Notify方法关联起来呢?只需通过事件绑定即可实现,具体过程如下列代码:

Employee employee = new Employee();

Admin admin = new Admin();

employee.PlayGame += new DelegateClassHandle(admin.Notify);

employee.Games();

请大家注意事件绑定的代码:

employee.PlayGame += new DelegateClassHandle(admin.Notify);

通过DelegateClassHandle将两个类的交互进行了绑定,当employee.Games方法调用后,触发PlayGame事件,而该事件将被委托给admin的Notify方法处理,通知董事长有雇员在上班时间玩游戏。

但董事长并不满足这种简单的通知,他还想知道究竟是谁在上班时间违反规定。显然,现在委托对象必须传递必要的参数才行,这个要求也可以很容易地办到。事件的参数可以设置为任何类型的数据,在.NET框架中,还提供了事件参数基类EventArgs专门用于传递事件数据。

从该EventArgs类派生一个自定义的事件参数类CustomeEventArgs,这个类型将携带雇员姓名和年龄信息:

public class CustomeEvetnArgs : EventArgs

{

string name = "";

int age = 0;

public CustomeEvetnArgs()

{ }

public string Name

{

get { return https://www.360docs.net/doc/7c9108322.html,; }

set { https://www.360docs.net/doc/7c9108322.html, = value; }

}

public int Age

{

get { return this.age; }

set { this.age = value; }

}

}

修改委托类型DelegateClassHandle的定义,让其携带必要的参数:

public delegate void DelegateClassHandle(object sender, CustomeEvetnArgs e);

雇员类的代码修改后如下:

public class Employee

{

private string _name;

public string Name

{

get { return _name; }

set { _name = value; }

}

private int _age;

public int Age

{

get { return _age; }

set { _age = value; }

}

public event DelegateClassHandle PlayGame;

public void Games()

{

if (PlayGame != null)

{

CustomeEvetnArgs e = new CustomeEvetnArgs();

https://www.360docs.net/doc/7c9108322.html, = this._name ;

e.Age = this._age;

PlayGame(this, e);

}

}

}

在Games方法中,首先新建一个CustomeEventArgs对象,然后设置了必要的属性Name和Age。

董事长的通知方法也必须相应地进行修改:

public class Admin

{

public void Notify(object sender, CustomeEvetnArgs e)

{

System.Console.WriteLine(https://www.360docs.net/doc/7c9108322.html,+" is "+e.Age.ToString());

}

}

将两个类型对象进行关联的代码也需要进行相应的修改:

Employee employee = new Employee();

https://www.360docs.net/doc/7c9108322.html, = "Mike";

employee.Age = 25;

Admin admin = new Admin();

employee.PlayGame += new DelegateClassHandle(admin.Notify);

employee.Games();

修改后的代码运行的结果是,当Mike调用Games方法玩游戏时,会自动触发PlayGame事件,而该事件携带相关信息通知admin,后者的Notify方法将接收到数据并输出“Mike is 25”,告诉董事长是Mike,25岁,正在上班时间玩游戏。

委托是可以多路广播(Mulitcast)的,即一个事件可以委托给多个对象接收并处理。在上面的用例中,如果有另一位经理与董事长具有同样的癖好,也可以让委托对象将雇员的PlayGame事件通知他。

首先定义经理类:

public class Manager

{

public void Notify(object sender, CustomeEvetnArgs e)

{

System.Console.WriteLine(sender.ToString() + "-" + https://www.360docs.net/doc/7c9108322.html,);

}

}

经理Manager类型的Notify方法与Admin一致,他也接受到相应的信息。

委托的多路广播绑定的方法仍然是使用+=运算符,其方法如下面的代码所示:

Employee employee = new Employee();

https://www.360docs.net/doc/7c9108322.html, = "Mike";

employee.Age = 25;

Admin admin = new Admin();

Manager manager = new Manager();

employee.PlayGame += new DelegateClassHandle(admin.Notify);

employee.PlayGame += new DelegateClassHandle(manager.Notify);

employee.Games();

执行该方法,读者将看到admin和manager的Notify方法都会被事件通知并调用执行。通过这样的方法,董事长和经理都会知道Mike在玩游戏了。

如果董事长不希望经理也收到这个通知,该如何解除PlayGame对manager的事件绑定呢?同样非常简单,在employee.Games方法被调用前执行下列语句即可:

employee.PlayGame -= new DelegateClassHandle(manager.Notify);

最后需要提醒读者注意的,Employee类中的Games方法在触发事件PlayGame之前需要判

断该事件是否为null。当employee对象的Games方法触发事件PlayGame后,必须有一个目标函数来处理这个事件,而该语句正是判断该目标函数是否存在。如果将这个判断去掉,且对事件不进行任何绑定而直接调用Games方法,程序将在事件PlayGame处弹出一个NullReferenceException的异常。

读者能够从委托与事件的代码中得出什么结论吗?两个需要存在调用关系的类型,在各自的实现中却没有编写实际的调用代码,它们只是通过一个事件和一个第三方的委托类型完成了消息的传递过程。两个类型之间不存在任何的紧密耦合,它们看似松散地通过一个委托对象中通信,实现了本书一直宣传的“高聚合”和“低耦合”观点。

事件是特殊的委托(这是个人理解)

首先介绍一个为什么要在事件中引入委托这个概念:

事件是对象发送的消息,以发信号通知操作的发生。操作可能是由用户交互(例如鼠标单击)引起的,也可能是由某些其他的程序逻辑触发的。引发事件的对象称为事件发送方。捕获事件并对其作出响应的对象叫做事件接收方。

在事件通信中,事件发送方类不知道哪个对象或方法将接收到(处理)它引发的事件。所需要的是在源和接收方之间存在一个媒介(或类似指针的机制)。.NET Framework 定义了一个特殊的类型(Delegate),该类型提供函数指针的功能。

原理简介:

在C#中,一个类可以有域(Fields)、属性(Properties)、方法(Methods)、索引(Indexs)、事件(Events),以及委托(delegate)等成员,其中事件(Events)成员就是用来声明一个类事件的。在类中声明一个事件成员一般采用如下的语法形式:

Public event 代理名事件名

如在某个类中申明一个MyClick事件成员,其语法如下:

Public event DelegateName(自定义的一个委托) MyClick;

在C#中,增加了一个新的数据类型delegate(代表)来解决事件处理问题。代表数据类型非常类似于C语言中的指针,其与指针不同的是,其是代码是安全的,可管理的。这里是 DelegateName可以是系统已经提供的代理EventHandler,也可以是自己预先定义好的委托,委托的定义如下:

Public delegate [返回值] delegatename(委托的名字)(参数列表……..)

(它可以放在类外面,也可以放到类中,只要能在代码中访问到即可)

这里注意:如果是这个委托为事件而申明的,这里的返回值的类型就只能是void类型的,否则就要出现问题.

在C#中,通过使用delegate,你可以通过“+=”(加等于)操作符非常容易地为.Net对象中的一个事件添加一个甚至多个响应方法;还可以通过非常简单的“-=”(减等于)操作符取消这些响应方法。如下面为temp按钮添加Click事件的语句:

在上面声明事件的语句中,Eventhandler是一个delegate(代表)类型,其在.Net类库中如下声明的:

public delegate void EventHandler(object sender,EventArgs e);

这样,所有形如:void 函娄名(object 参数名,EventArgs 参数名);的函数都可以作为Control 类的Click事件响应方法了。如下面所定义的一个事件响应方法:

private void button1_Click(object sender, System.EventArgs e)

由于是通过delegate(代表类型)来处理事件,因此,可能通过累加使一个事件具有多个

响应方法;与此同时,还可以使一个方法作为多个事件的响应方法。(注意:在C#语言类中的event成员后面只能出现“+=”与“-=”两个表示添加与取消事件响应函数的操作符。)

不管是https://www.360docs.net/doc/7c9108322.html,还是一般的Windows Forms 编程,在C#中,基本上我们遇到的事件响应方法都是说明成如下的形式:

private void button1_Click(object sender, System.EventArgs e)

(参考其他资料)

一个事件响应方法的存取权限、返回值类型、参数及类型甚至方法名称等是否都必须固定不变呢?答案是:不是!

一般情况下,事件的响应方法中都有两个参数,其中一个代表引发事件的对象即sender,由于引发事件的对象不可预知的,因此我们把其声明成为object类型,所有的对象都适用。第二个参数代表引发事件的具体信息,各种类型的事件中可能不同,这要根据类中事件成员的说明决定。

我们知道,事件是通过delegate(代表) 来处理的。假设将要表示事件的代表说明成如下形式:

delegate int MyEventHandler(object sender, ToolBarButtonClickEventArgs e);

则当涉及上面的事件响应函数声明时,就须要声明成如下的形式:

private int MyTest(object sender,ToolBarButtonClickEventArgs e)

{

}

在给对象添加事件响应方法时就可以用如下的代码实现:

Control.Event+=new MyEventHandler(MyTest);

下面是我根据对委托的理解,自己编写的代码,

注意目的是为了深入理解事件是怎样和委托结合的。我的想法是这样的:既然microsft 已经为button按钮写了onclick事件了(不传递任何参数进入事件),我就打算重新添加一个MyClick事件,当按钮的onclick事件发生的时候,我就重写默认的onclick事件,执行自己添加的MyClick事件,并传递参数进入事件(MyClick)中进行处理。

首先添加一个自定义的按钮MyButton,它继承于System.Window.Forms.Button类的.代码如下:

namespace ExampleAddEventForm

{

public delegate void MyDelegate(object sender,object myevenargs);//这里把申明委托放到了类外,其实放到类中也一样,只是引用地址不同而已。

public class MyButton:System.Windows.Forms.Button

{

protected override void OnClick(EventArgs e)

{//重写默认的onclick方法,触发自己的事件

TriggerEvent();

}

public event MyDelegate MyDelegateEvent;//申明一个事件

public void TriggerEvent()

{

if (MyDelegateEvent != null)

{

MyEvenArgs myevenargs = new MyEvenArgs();

myevenargs.FirstName = "cc";

https://www.360docs.net/doc/7c9108322.html,stName = "changchang";

MyDelegateEvent(this,myevenargs);

}

}

}

}

上面的MyEvenArgs类是我自定义的类,它继承与系统提供的System.EvenArgs类注意目的是为了传入参数进入方法。

Namespace ExampleAddEventForm

{

class MyEvenArgs:System.EventArgs

{

private string firstname;

public string FirstName

{

get { return firstname; }

set { firstname = value; }

}

private string lastname;

public string LastName

{

get { return lastname; }

set { lastname = value; }

}

}

}

到现在为止,我们已经实现了自己的按钮(自定义了事件和委托,并重写了microsft为我们提供的onclick事件,执行我们的OnClick事件)和Onclick事件中需要的传递参数的MyEvenArgs类

下面就把我们写的MyButton按钮放到页面上(不是拖放到页面上,这是不可能的),我们至少都要在InitializeComponent方法中加载到页面上

private MyButton mybutton

private void InitializeComponent()

{

this.mybutton = new MyButton();

this.SuspendLayout();

this.mybutton.Location = new System.Drawing.Point(71, 99);

https://www.360docs.net/doc/7c9108322.html, = "mybutton";

this.mybutton.Size = new System.Drawing.Size(150, 23);

this.mybutton.TabIndex = 0;

this.mybutton.Text = "Override Button";

https://www.360docs.net/doc/7c9108322.html,eVisualStyleBackColor = true;

this.mybutton.MyDelegateEvent += new.MyDelegate(this.MyButton_Click);

this.Controls.Add(mybutton);

}

这时回到设计界面提示错误(这是正常的)(没有刷新)。从这里可以看到

mybutton.MyDelegateEvent += new MyDelegate(MyButton_Click);

这句话就是注册事件,用自定义button中事件执行MyButton_Click函数方法,其实这就是事件处理程序。

返回到后台代码的如下:(这里只是简单的提示有用的消息)public void MyButton_Click(object sender, MyEvenArgs message)

{

MessageBox.Show(message.FirstName+https://www.360docs.net/doc/7c9108322.html,stName);//这个就是传递个事件处理程序中的参数

MessageBox.Show("this is a custom button's click!");

}

现在代码就结束了,运行程序就弹出“this is a custom button’s click”的提示

这里我主要理解了事件的机制和原理,有什么不正确的请朋友们及时的提出,一起讨论,共同进步。

C#委托及事件

C#委托及事件 在C#中,委托(delegate)是一种引用类型,在其他语言中,与委托最接近的是函数指针,但委托不仅存储对方法入口点的引用,还存储对用于调用方法的对象实例的引用。 简单的讲委托(delegate)是一种类型安全的函数指针,首先,看下面的示例程序,在C++中使用函数指针。 首先,存在两个方法:分别用于求两个数的最大值和最小值。 int Max(int x,int y) { return x>yx:y; } int Min(int x,int y) { return x } 上面两个函数的特点是:函数的返回值类型及参数列表都一样。那么,我们可以使用函数指针来指代这两个函数,并且可以将具体的指代过程交给用户,这样,可以减少用户判断的次数。 下面我们可以建立一个函数指针,将指向任意一个方法,代码如下所示: 建立一个委托类型,并声明该委托可以指向的方法的签名(函数原型)delegate void MyDelegate(int a,int b); 2.建立一个委托类的实例,并指向要调用的方法 用委托类实例调用所指向的方法 int c=md(4,5); 下面通过实例来演示C#中委托的使用。

案例操作020601:利用委托实现方法的 动态调用 首先,添加如下控件: 两个RadioButton,分别用来让用户选 择求最大值以及求最小值 二个TextBox,用来输入两个操作数 一个TextBox,用来显示运算结果 一个Button,用来执行运算 界面如下图所示: 下一步,在窗口中添加两个方法:Max,Min,这两方法的代码如下: int Max(int x,int y) { return x>yx:y; } int Min(int x,int y) { return x } 窗口中的代码,如下图所示:

C#委托事件详解

C# 中的委托和事件 引言 委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在。本文中,我将通过两个范例由浅入深地讲述什么是委托、为什么要使用委托、事件的由来、.Net Framework中的委托和事件、委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论。 将方法作为方法的参数 我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这两个最简单的方法,它们不过是在屏幕上输出一句问候的话语: public void GreetPeople(string name) { // 做某些额外的事情,比如初始化之类,此处略 EnglishGreeting(name); } public void EnglishGreeting(string name) { Console.WriteLine("Morning, " + name); } 暂且不管这两个方法有没有什么实际意义。GreetPeople用于向某人问好,当我们传递代表某人姓名的name参数,比如说“Jimmy”,进去的时候,在这个方法中,将调用EnglishGreeting方法,再次传递name参数,EnglishGreeting则用于向屏幕输出“Morning, Jimmy”。

现在假设这个程序需要进行全球化,哎呀,不好了,我是中国人,我不明白“Morning”是什么意思,怎么办呢?好吧,我们再加个中文版的问候方法: public void ChineseGreeting(string name){ Console.WriteLine("早上好, " + name); } 这时候,GreetPeople也需要改一改了,不然如何判断到底用哪个版本的Greeting问候方法合适呢?在进行这个之前,我们最好再定义一个枚举作为判断的依据: public enum Language{ English, Chinese } public void GreetPeople(string name, Language lang){ //做某些额外的事情,比如初始化之类,此处略 swith(lang){ case Language.English: EnglishGreeting(name); break; case Language.Chinese: ChineseGreeting(name); break; } } OK,尽管这样解决了问题,但我不说大家也很容易想到,这个解决方案的可扩展性很差,如果日后我们需要再添加韩文版、日文版,就不得不反复修改枚举和GreetPeople()方法,以适应新的需求。 在考虑新的解决方案之前,我们先看看 GreetPeople的方法签名:

唯一看明白额委托与事件讲解

一、在控制台下使用委托和事件 我们都知道,C#中有“接口”这个概念,所谓的“接口”就是定义一套标准,然后由实现类来具体实现其中的方法,所以说“接口,是一组类的抽象”。同样道理,我们可以将“委托”理解为“方法的抽象”,也就是说定义一个方法的模板,至于这个方法具体是怎么样的,就由方法自己去实现。 我们知道接口的最大好处就是可以实现多态,同理,“委托”是可以实现方法的多态,当我们想调用某个具体方法的时候,我们不直接调用这个方法,而是去调用这个委托。当然,我们必须在具体方法和委托之间建立某种关联。 下面我们来看例子。 首先,我们定义一个委托: public delegate void SaySomething(string name); 这跟抽象方法的语法格式很相似,只是多了一个关键字delegate。既然是对方法的一种抽象,那么我们最关注的当然就是方法的返回值以及方法的参数了。所以上面红色的部分就是我们定义出来的一个规矩,如果某个方法想委托我去做事,那么请你遵循我的规矩,就是返回值为void,参数为一个字符串。我们这个委托的含义是,当某个人来了,就向他说点东西。 好,既然我们已经定义了这个规矩,下面我们就定义具体的方法了。 public void SayHello(string name) { Console.WriteLine("Hello," + name + "!"); } public void SayNiceToMeetYou(string name) { Console.WriteLine("Nice to meet you," + name + "!"); } 我们这里一共定义了两个方法,一个是向某人说Hello,另一个是向某人说Nice to meet you。我们看到,这里定义的两个方法的返回值和参数跟我们前面定义的“委托”是一致的。 接下来,我们来看事件。 public event SaySomething come;

委托事件1

委托 定义委托的语法和定义方法比较相似,只是比方法多了一个关键字delegate,我们都知道方法就是将类型参数化,所谓的类型参数化就是说该方法接受一个参数,而该参数是某种类型的参数,比如int、string等等;而委托是将方法参数化,说了上面的那个类型参数化之后,相信你也能猜到方法参数化的意思了,对,就是将方法作为一个参数传到一个委托中。 首先来看看声明委托的语句: public deletate void MyDelegate(); public:访问修饰符delegate:关键字void:返回类型MyDelegate:委托名称( ):参数列表 看到声明大家会想了,为什么该委托的返回值,参数列表要这样的,我不能返回一个string,一个int么?我不能给委托加几个参数么?答案是:当然可以,但委托的定义是相对于方法来说的,因为得你的委托最终是要来注册方法的,而你的方法是具有某种签名的,所以你要给怎样签名的方法来声明一个委托,该委托就要和该方法具有同等的签名,就类似于你用一个int 类型的变量去接受一个string类型的值,显然是不行的(个人理解).... * 委托只要定义就可以了,我们并不需要关心他的实现 委托的使用 注册委托有两种方法: 第一种:直接将方法赋值[=]或者用“+=”给一个委托==>委托名=[+=] 方法名 第二种:委托本质也是一个类,只是一个特殊的类,所以我们也可以实例化一个委托对象通过委托构造函数来注册委托==》委托名对象名= new 委托名(方法名)

了解了委托的声明和使用,我们就可以来看小例子来加深理解了 首先看看界面: 界面上就是简单的四个按钮两个属于委托,两个属于事件,都是一个用来执行,一个用来干扰,以便于来理解委托事件 然后看后台代码,首先我定义了一个Test类,声明委托,实例了委托,还声明了事件,写了个方法用来触发事件,代码如下: 1public class Test 2 { 3//声明一个委托 4public delegate void MyDelegate(); 5 6//创建一个委托实例 7public MyDelegate myDel; 8//声明一个事件 9public event MyDelegate EventMyDel; 10 11//事件触发机制(必须和事件在同一个类中) 外界无法直接用EventMyDel()来触发事件 12public void DoEventMyDel() 13 { 14 EventMyDel(); 15 } 16 }

委托与事件 机制

Button1.Click+=new EventHandler(Button1_Click);-----------------@1 大家都熟悉的一段代码,Button1.Click是事件(也可以说是一条委托链),EventHandler 是委托,Button1_Click是订阅事件的人,也可以说是委托的人。 通过这样的机制,一个事件可以有多个订阅者,从而可以实现点击button可以响应多个方法。委托,顾名思义,委托给别人。 事件,“发布者/订阅者” 模式,发布者发布一个事件,订阅者订阅这个事件,当事件触发时,就会通知订阅者。通知这个过程是通过委托来实现的。 大家想象一下这个情景,经理有一个项目,计划A君负责美工方面,B君负责程序方面,将项目一分为二;于是一天,在用餐的时候告诉他们这个计划。 发布者:经理---------@2 订阅者订阅这个事件原因:A,B君是经理的部下 -------------@3 事件:经理分配了A,B一个项目-------------@4 触发事件的原因:经理有个计划----------------@5 通知方式(委托):”在用餐的时候告诉“方式----------------@6 public delegate void OneThing(object sender, CustomEventArgs e);定义一个委托,返回值为空,委托名OneThing,相当于@1中的EventHandler,有两个参数分别为触发事件的对象和事件信息。 Custom EventArgs必须继承于EventArgs public class CustomEventArgs : EventArgs

论C#中的委托与事件

论C#中的委托与事件 在C#里,委托与事件类是两个不易理解的概念。主要阐述对委托与事件的理解,同时结合Observer设计模式与.NET Framework规范,针对生活中的案例来辨析委托与事件的应用。 标签:委托;事件Observer设计模式;.NET Framework C#中的委托类似于C++中的函数指针,功能却更多。事件是在委托的基础上的一种结构,类似于委托的变量,在界面的控件中处处都有应用。 1 什么是委托 委托的申明格式:修饰符delegate 返回值数据类型委托名(形参列表)。 例如:Delegate int AbcDel(string s, bool b);是一个委托申明,每一个委托都有自己的签名,就是说AbcDel这个委托有string 和bool类型的形参,返回一个int类型数据,即具有这样的函数签名。委托类似于函数指针,它能够引用函数,通过传递地址的机制完成。委托是一个类,当对它实例化时,要提供一个引用函数,将其作为它构造函数的参数。例如:private int AbcFun (string str, bool bln){},则可以把这个函数传给AbcDel的构造函数,因为它们签名一致。AbcDel sd = new SomeDelegate(AbcFun),sd 引用了AbcFun,也就是说,AbcFun已被sd所登记注册,如果你调用sd,AbcFun这个函数即会被调用。 2 事件的理解 事件的申明格式:修饰符event 委托名事件名; 例如:public event AbcDel Boil;//AbcDel为委托名 Boil事件的声明与之前委托变量sd的声明唯一的区别是多了event关键字。声明事件类似于声明一个委托类型的变量。 3 Observer设计模式 假设热水器系统由两部分组成:热水器、警报器,由不同厂商进行了组装。热水器仅负责烧水;警报器在水烧开时发出警报,当水温超过95度,就发出警报。我们需要应用委托与事件来模拟此过程。 Observer设计模式是为了定义对象间的一种一对多的依赖关系,以便于当一个对象的状态改变时,其他依赖于它的对象会被自动告知并更新。Observer模式是一种松耦合的设计模式。它包括两类对象:

C#委托与事件以及应用

这些很重要在MVC EF4.1 里都会有很多拉姆达表达式的影子在做组件开发用户控件开发事件的运用一定也是少不了的稍微深入点儿的说用于两个对象之间的通讯用来解耦用委托事件是很不错的选择而设计模式里的观察者模式也是基于委托事件的应用还有做winform 开发的里的线程WPF SL 的异步调用等都是有这委托的影子的所以这个还是很重要的。也是一定要掌握的~ 希望通过这篇文章能让大家更加了解委托以及如何运用~ 一.委托以及延伸 先看下MSDN 的介绍吧~------ delegate 通俗的说委托就是可以实现把方法做为变量来传递 1.先写个最简单的委托的用法 静态的和非静态方法的 结果会输出 您好wlf

Hello wlf 这是最原始的委托 2. 进化为匿名方法 声明完委托后还要声明方法是不是很麻烦如果不声明方法用匿名方法可以帮我们看 代码减少了很多吧~ 3.再进化为拉姆达表达式 上面的虽然简单了不少但是还能更简单的用拉姆达表达式~ 看这就是拉姆达表达式的演变一定要会这个~ 因为在EF LINQ 等有很多用拉姆达表达式的~ 4.用Action 和Func继续简化 上面的代码以及很简单了但是还有个很不爽的一点~ 要声明委托!可以不声明么?当然可以~ 先看MSDN介绍Action和Func 通俗的讲这两个都是用来帮你声明委托 Action 用于帮你声明没用返回值的委托Func则是有返回值的最后一个参数为返回值

看~ 以前的版本总是要声明一个HelloWorld 的委托现在只有两行代码就可以了下面顺便掩饰了有返回值的func 的例子。第一个参数是传递 参数的类型第二个是返回值的类型~ 这里说下这俩函数都有16个重载~ 所以多个参数是没问题的~ 5.说说委托的好处 委托的好处应用文章开始已经说了很多了这里就拿文章开头的例子体会下委托的好处 当我们再多一种语言来问好时只需增加一种Action 即可而不需要改动sayHello 方法否则这里将充满了if else 的判断 6.工作里的应用 再LINQ 或EF 里都有个很重要的数据刷选的功能WHERE 它的参数就是Func 直接上代码自己看注释~

unity3D学习之委托、事件全解析(二)

废话就不多说了,直接进入今天的主题-事件在我们所接触到的事件一般分两种:一种是自定义的,自定义的事件需要自己对其进行赋值。 一种是控件提供方定义的,如:ngui,控件事件只需要查找控件定义的事件列表,选择所需要的进行操作即可。 当然,我们的话题是上面第一种啦。 实例模拟场景为:文章来自【狗刨学习网】 游戏战斗中,猪脚在指定的一片区域中,存在4只怪物,他的目的就是一只一只找到并消灭该区域的怪物。 简易流程:查询目标->行走->攻击,依次循环 ok,在此,我用代码快速模拟这样一个情景,建立一个Hero类,如下: using UnityEngine; using System.Collections; using System.Collections.Generic; using System;

// 英雄角色 public class Hero : MonoBehaviour { //当前目标id public int TargetID=0; public List ListMonster; void Start() { InvokeRepeating("selectTarget", 0.3f, 0.3f); } // 查询目标 private void selectTarget() { if (TargetID==0) { if (ListMonster.Count > 0) { for (int i = 0; i <= ListMonster.Count; i++) { TargetID = ListMonster[i];[/i] WalkToTarget(TargetID);

你可能不知道的陷阱:C#委托和事件的困惑

你可能不知道的陷阱:C#委托和事件的困惑 . 问题引入 通常,一个C 语言学习者登堂入室的标志就是学会使用了指针,而成为高手的标志又是“玩转指针”。指针是如此奇妙,通过一个地址,可以指向一个数,结构体,对象,甚至函数。最后的一种函数,我们称之为“函数指针”(和“指针函数”可不一样!)就像如下的代码: 1 2 3 int func(int x); /* 声明一个函数 */ int (*f) (int x); /* 声明一个函数指针 */ f=func; /* 将func 函数的首地址赋给指针f */ C 语言因为函数指针获得了极强的动态性,因为你可以通过给函数指针赋值并动态改变其行为,我曾在单片机上写的一个小系统中,任务调度机制玩的就是函数指针。 在.NET 时代,函数指针有了更安全更优雅的包装,就是委托。而事件,则是为了限制委托灵活性引入的新“委托”(之所以为什么限制,后面会谈到)。同样,熟练掌握委托和事件,也是C#登堂入室的标志。有了事件,大大简化了编程,类库变得前所未有的开放,消息传递变得更加简单,任何熟悉事件的人一定都深有体会。 但你也知道,指针强大,高性能,带来的就是危险,你不知道这个指针是否安全,出了问题,非常难于调试。事件和委托这么好,可是当你写了很多代码,完成大型系统时,心里是不是总觉得怪怪的?有当年使用指针时类似的感觉? 如果是的话,请看如下的问题: 1. 若多次添加同一个事件处理函数时,触发时处理函数是否也会多次触发? 2. 若添加了一个事件处理函数,却执行了两次或多次”取消事件“,是否会报错? 3. 如何认定两个事件处理函数是一样的? 如果是匿名函数呢? 4. 如果不手动删除事件函数,系统会帮我们回收吗? 5. 在多线程环境下,挂接事件时和对象创建所在的线程不同,那事件处理函数中的代码将在哪个线程中执行? 6. 当代码的层次复杂时,开放委托和事件是不是会带来更大的麻烦? 列下这些问题,下面就让我们讨论这些”尖酸刻薄“的问题。 二. 事件订阅和取消问题 我们考虑一个典型的例子:加热器,加热器内部加热,在达到温度后通知外界”加热已经完成“。 尝试写下如下测试类:

C#委托、事件、自定义事件的理解

C#委托、事件、自定义事件的理解 一、委托 委托类似于函数指针,但函数指针只能引用静态方法,而委托既能引用静态方法,也能引用实例方法。委托使用分三步:1、委托声明。2、委托实例化。3、委托调用。 例程一: using System; namespace 委托 { delegate int NumOpe(int a,int b); //委托声明 class Class1 { static void Main(string[] args) { Class1 c1 = new Class1(); NumOpe p1 = new NumOpe(c1.Add); //委托实例化 Console.WriteLine(p1(1,2)); //委托调用 Console.ReadLine(); } private int Add(int num1,int num2) { return(num1+num2); } } } 例中,委托NumOpe引用了方法Add。 委托声明了以后,就可以象类一样进行实例化,实例化时把要引用的方法(如:Add)做为参数,这样委托和方法就关联了起来,就可以用委托来引用方法了。 委托和所引用的方法必须保持一致: 1)参数个数、类型、顺序必须完全一致。2)返回值必须一致。 二、事件 事件有很多,比如说鼠标的事件:MouserMove,MouserDown等,键盘的事件:KeyUp,KeyDown,KeyPress。 有事件,就会有对事件进行处理的方法,而事件和处理方法之间是怎么联系起来的呢?委托就是他们中间的桥梁,事件发生时,委托会知道,然后将事件传递给处理方法,处理方法进行相应处理。

C#委托与事件

我们抛弃各种C#参考书中桀骜难懂的事件与委托概念,设想一个情景来理解事件与委托的使用:有一家IT公司,董事长不希望自己的雇员在上班时间玩游戏,但又不可能每时每刻都盯着每个雇员,因此,他希望使用一种新的方式实现监视雇员的效果:如果有雇员违反规定,某个设备或专门的监查人员将自动发出一个消息通知他,董事长只需要在事情发生时进行处理。 因此,这个用例实际上是两种类型——董事长类与雇员类——之间的交互,下面的代码将给读者展示如何使用委托与事件机制实现这种交互: 首先,我们需要在董事长类与雇员类之间定义一个委托类型,用于传递两者之间的事件,这个类型就是一个监视设备或专门负责打小报告的监查人员: public delegate void DelegateClassHandle(); 定义一个委托的过程类似方法的定义,但它没有方法体。定义委托一定要添加关键字delegate。由于定义委托实际上相当一个类,因此可以在定义类的任何地方定义委托。另外,根据委托的可见性,也可以添加一般的访问修饰符,如public、private和protected。 委托的返回值类型为void,这并非表示委托类型本身带有返回值,该返回值类型是指委托的目标函数类型,即它委托的一个事件处理函数返回值是void类型。 新建一个雇员类Employee,其代码如下: public class Employee { public event DelegateClassHandle PlayGame; public void Games() { if (PlayGame != null) { PlayGame(); } } } 雇员类Employee代码中定义了一个DelegateClassHandle类型的事件PlayGame,它的定义方式也很特殊,首先必须使用关键字event,表示PlayGame是一个事件,同时还必须声明该事件的委托类型为DelegateClassHandle,即将来由该类型的委托对象负责通知事件。 如果有雇员开始玩游戏,它将执行Games方法,而只要该方法一被调用,就会触发一个事件PlayGame,然后董事长就会收到这个事件的消息——有人在玩游戏了。 董事长类代码如下,他有一个方法Notify用于接收消息: public class Admin { public void Notify() {

c#中如何深入理解“事件与委托”

C#中如何深入理解“事件与委托”?(初学者必看) 2008年01月19日星期六 22:57 事件与委托似乎很难以理解,这是因为它们的使用方式与常用的编码有很大的差别,例如通常编写的都是同步代码,调用一个类型的方法,会即刻出现方法执行的结果,这是符合逻辑的。但在某些情况中,同步代码未必满足需求,拿公共汽车来打个比方,如果交通管制中心希望每一辆公车到达一个站点时都发送给自己一个信号以便自己能够随时掌握交通状况,使用同步代码,公汽对象肯定需要调用管制中心对象,这样就出现了我们一直不愿意看到的情况:两个类型紧密地耦合在一起。既然要其它类型对自己的行为作出反应,亲自调用其类型的方法似乎不可避免,在同步代码中,很难避免这种紧密的类型调用关系。 另一个差别是在一般情况下,我们只将属性作为参数传递给方法,而很少会考虑将一个方法传递给另一个方法。 我们抛弃各种C#参考书中桀骜难懂的事件与委托概念,设想一个情景来理解事件与委托的使用:有一家IT公司,董事长不希望自己的雇员在上班时间玩游戏,但又不可能每时每刻都盯着每个雇员,因此,他希望使用一种新的方式实现监视雇员的效果:如果有雇员违反规定,某个设备或专门的监查人员将自动发出一个消息通知他,董事长只需要在事情发生时进行处理。 因此,这个用例实际上是两种类型——董事长类与雇员类——之间的交互,下面的代码将给读者展示如何使用委托与事件机制实现这种交互: 首先,我们需要在董事长类与雇员类之间定义一个委托类型,用于传递两者之间的事件,这个类型就是一个监视设备或专门负责打小报告的监查人员: public delegate void DelegateClassHandle(); 定义一个委托的过程类似方法的定义,但它没有方法体。定义委托一定要添加关键字delegate。由于定义委托实际上相当一个类,因此可以在定义类的任何地方定义委托。另外,根据委托的可见性,也可以添加一般的访问修饰符,如public、private和protected。 委托的返回值类型为void,这并非表示委托类型本身带有返回值,该返回值类型是指委托的目标函数类型,即它委托的一个事件处理函数返回值是void类型。 新建一个雇员类Employee,其代码如下: public class Employee { public event DelegateClassHandle PlayGame; public void Games() { if (PlayGame != null) { PlayGame(); } } }

委托和事件的区别

委托和事件的区别(讲的很详细)--转 委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在。本文中,我将通过两个范例由浅入深地讲述什么是委托、为什么要使用委托、事件的由来、.Net Framework中的委托和事件、委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论。 将方法作为方法的参数 我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这两个最简单的方法,它们不过是在屏幕上输出一句问候的话语: public void GreetPeople(string name) { // 做某些额外的事情,比如初始化之类,此处略 EnglishGreeting(name); } public void EnglishGreeting(string name) { Console.WriteLine("Morning, " + name); } 暂且不管这两个方法有没有什么实际意义。GreetPeople用于向某人问好,当我们传递代表某人姓名的name参数,比如说“Jimmy”,进去的时候,在这个方法中,将调用EnglishGreeting方法,再次传递name参数,EnglishGreeting则用于向屏幕输出“Morning, Jimmy”。 现在假设这个程序需要进行全球化,哎呀,不好了,我是中国人,我不明白“Morning”是什么意思,怎么办呢?好吧,我们再加个中文版的问候方法: public void ChineseGreeting(string name){ Console.WriteLine("早上好, " + name); } 这时候,GreetPeople也需要改一改了,不然如何判断到底用哪个版本的Greeting问候方法合适呢?在进行这个之前,我们最好再定义一个枚举作为判断的依据: public enum Language{ English, Chinese } public void GreetPeople(string name, Language lang){ //做某些额外的事情,比如初始化之类,此处略 swith(lang){ case Language.English:

委托与事件的区别

委托与事件的区别 委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C# 时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没 有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在。本文中,我将通过两个 范例由浅入深地讲述什么是委托、为什么要使用委托、事件的由来、.Net Framework中的委托和 事件、委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论。 将方法作为方法的参数 我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这两个最简单的方法,它们不过是在屏幕上输出一句问候的话语: public void GreetPeople(string name) { // 做某些额外的事情,比如初始化之类,此处略 EnglishGreeting(name); } public void EnglishGreeting(string name) { Console.WriteLine("Morning, " + name); } 暂且不管这两个方法有没有什么实际意义。GreetPeople用于向某人问好,当我们传递代表某人姓 名的name参数,比如说“Jimmy”,进去的时候,在这个方法中,将调用EnglishGreeting方法,再 次传递name参数,EnglishGreeting则用于向屏幕输出“Morning, Jimmy”。 现在假设这个程序需要进行全球化,哎呀,不好了,我是中国人,我不明白“Morning”是什么意思,怎么办呢?好吧,我们再加个中文版的问候方法: public void ChineseGreeting(string name){ Console.WriteLine("早上好, " + name); } 这时候,GreetPeople也需要改一改了,不然如何判断到底用哪个版本的Greeting问候方法合适呢?在进行这个之前,我们最好再定义一个枚举作为判断的依据: public enum Language{ English, Chinese }

委托与事件代码详解与(Object_sender,EventArgs_e)详解

1 委托与事件代码详解与(Object sender,EventArgs e )详解 using System; using System.Collections.Generic; using System.Text; namespace @Delegate //自定义命名空间,新建控制台程序,命名后自动添加 { // 热水器 public class Heater { private int temperature; public string type = "RealFire 001"; // 添加型号作为演示 public string area = "China Xian"; // 添加产地作为演示 //声明委托 public delegate void BoiledEventHandler(Object sender, BoiledEventArgs e);/*BoiledEventHandler 相当于一个类型(属于委托),与String 地位等同,它所声明的参数形式与后来它要包含的方法的参数形式必须是一致的,例如黄色加亮部分的方法*/ public event BoiledEventHandler Boiled; /*声明事件。相当于封装BoiledEventHandler 类型的对象(变量) Boiled ,使之在类的内部总是pravite 的,而使+=和-=的访问权限为声明时的修饰符权限*/ // 定义BoiledEventArgs 类,传递给Observer 所感兴趣的信息。//Observer 设计模式 public class BoiledEventArgs : EventArgs { public readonly int temperature; public BoiledEventArgs(int temperature) { this.temperature = temperature; } } // 可以供继承自 Heater 的类重写,以便继承类拒绝其他对象对它的监视//虚方法可以在类中覆盖重写 protected virtual void OnBoiled(BoiledEventArgs e) { if (Boiled != null) { // 如果有对象注册 Boiled(this, e); // 调用所有注册对象的方法 } } // 烧水。 public void BoilWater() { for (int i = 0; i <= 100; i++) {

C中的委托的使用和讲解

C#中的委托引言 委托和事件在.NetFramework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别(biè)得慌,混身不自在。本文中,我将通过两个范例由浅入深地讲述什么是委托、为什么要使用委托、事件的由来、.NetFramework中的委托和事件、委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论。 将方法作为方法的参数 我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这两个最简单的方法,它们不过是在屏幕上输出一句问候的话语: 1publicvoid GreetPeople(string name){ 2//做某些额外的事情,比如初始化之类,此处略 3EnglishGreeting(name); 4} 1publicvoid EnglishGreeting(string name){ 2Console.WriteLine("Morning,"+name); 3} 暂且不管这两个方法有没有什么实际意义。GreetPeople用于向某人问好,当我们传递代表某人姓名的name参数,比如说“JiYF”,进去的时候,在这个方法中,将调用EnglishGreeting方法,再次传递name参数,EnglishGreeting则用于向屏幕输出“Morning,JiYF”。 现在假设这个程序需要进行全球化,哎呀,不好了,我是中国人,我不明白“Morning”是什么意思,怎么办呢?好吧,我们再加个中文版的问候方法: 1publicvoid ChineseGreeting(string name){ 2Console.WriteLine("早上好,"+name); 3} 这时候,GreetPeople也需要改一改了,不然如何判断到底用哪个版本的Greeting 问候方法合适呢?在进行这个之前,我们最好再定义一个枚举作为判断的依据: 1publicenum Language{ 2English,Chinese 3} 1publicvoid GreetPeople(string name,Languagelang){ 2//做某些额外的事情,比如初始化之类,此处略 3swith(lang){

从一则案例看行政委托与行政授权的区别

(https://www.360docs.net/doc/7c9108322.html,) 从一则案例看行政委托与行政授权的区别 一、一则案例的引出 2013年4月26日,原告饶某以特快专递的方式向被告临川区温泉镇人民政府邮寄了政府信息公开的申请,其申请事项为:请求被告公开2010年、 2011年、2012年温泉镇人民政府每年征收的社会抚养费总数及用途。被告于2013年4月28日收到了原告的政府信息公开申请书,但是超过法定期限未予答复。原告遂依据相关的法律规定向法院提起行政诉讼。 被告辩称:原告饶某诉请公布社会抚养费的征收情况与其没有法律上的利害关系,其不具有提起行政诉讼的主体资格。社会抚养费的征收机关是当地计划生育行政部门,被告温泉镇人民政府是受委托的机关,不存在直接向原告饶某公开社会抚养费的征收情况,原告诉请的对象错误,被告主体不适格。 被告是否具有向原告履行政府信息公开的法定职责,取决于被告的诉讼主体是否适格。行政委托不同于行政授权,被告如果是受委托行政机关,就不具有诉讼主体资格。本案存在的主要问题是被告主体是否适格的问题。行政委托案件中,被告应是行使委托的行政机关。 二、行政委托与行政授权的区别 (一)行政委托的概念与构成要件 行政委托是指行政机关将其管辖权的一部分交由行政机关之外的组织或者个人,并以委托机关的名义行使行政职能。从广义上讲,行政机关之间的委托也应当包括在内。 行政委托的法律要件包括以下四个方面的内容: 1、委托必须有法定依据。行政机关必须在法律、法规及规章规定可以委托时,才能委托。没有法定依据的委托,叫做…自行委托?,是不合法的,也是无效的。 2、委托行政机关必须拥有法定权限。委托机关在进行行政委托时,其委托给受委托人的公权力必须是其自身合法拥有的职权。如果行政机关把一项本身不拥有的公权力委托给受委托人行使,这显然是滥用职权,超越权限的委托当然无效。

委托和事件的直接理解

初学者在理解委托和事件时常常被msdn搞糊涂,为了让初学.net的人快速应用.net的委托和事件模型编程,我在这里主要是提出理解的关键,以下代码都可直接运行,先看下面的代码。 using System; namespace delegeteTest { class delegeteClass { public delegate void fHandler(int a); //关键-此行可以看成类的声明 public fHandler f0; public void d(int a,int b ) { int c=a+b; f0(c); } } class test { public void output(int mun) { System.Console .WriteLine ("{0}",mun); } [STAThread] static void Main(string[] args) { test t=new test (); delegeteClass dc=new delegeteClass (); dc.f0 =new delegeteTest.delegeteClass.fHandler (t.output);//实例的初始化 dc.d(2,3); } } } 解释一下"关键": 实际上 public delegate void fHandler(int a);可以看成如下: class fHandler {.....} 类内部由编译器自动完成,是一个sealed类通过反汇编可以看到,是一个类的声明,它检查加入自己的函数的信息,如,返回值和参数类型

详解C#委托,事件与回调函数

详解C#委托,事件与回调函数 .Net编程中最经常用的元素,事件必然是其中之一。无论在https://www.360docs.net/doc/7c9108322.html,还是WINFrom开发中,窗体加载(Load),绘制(Paint),初始化(Init)等等。 “protected void Page_Load(object sender, EventArgs e)”这段代码相信没有人不熟悉的。细心一点一定会发现,非常多的事件方法都是带了“object sender, EventArgs e”这两个参数。这是不是和委托非常相似呢? 一、委托(有些书中也称为委派) 委托是什么呢?这个名字的意思已经赋予了我们想象的空间,你是编程的,你现在正在写一个https://www.360docs.net/doc/7c9108322.html,网页,而JS是你不熟悉的,于是你委托你的一位同事来帮助你完成JS部分。这就是委托,把你所不能做的事情交给其他人去做。而怎么知道是哪个人去做呢?当然是要知道名字!而为了区别名字一样的不同人,因此,需要描述一个特征。 在C#中,委托的作用是这样描述的:委托就像一个函数的指针,在程序运行时可以使用它们来调用不同的函数。这个其实和你委托同事完成 JS代码一样。如果有两位同事可以做这件事情,他们只要做的结果能够满足你的需求(就像一个接口),尽管他们做的过程不一样,并且作出的效果也不一样,但是,能够达到你的要求就可以了。 1、简单的委托 那委托需要承载哪些信息呢?首先,它存储了方法名,还有参数列表(方法签名),以及返回的类型。比如: delegate string/*返回类型*/ ProcessDelegate(int i); 这就是一个委托的定义。蓝色部分是声明委托的关键字,红色部分是返回的类型,而黑色部分是委托的类型名,和一个类名差不多,而()里的就是参数部分。它的意思是,你要使用这个委托来做事情的话,那么,做事情的方法必须满足以下条件:

C委托的妙文让你知道如何发挥委托的作用

C委托的妙文让你知道如何发挥委托的作用 Revised final draft November 26, 2020

委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就觉得心里别 (biè)得慌,混身不自在。本文中,我将通过两个范例由浅入深地讲述什么是委托、为什么要使用委托、事件的由来、.Net Framework中的委托和事件、委托和事件对Observer设计模式的意义,对它们的中间代码也做了讨论。 将方法作为方法的参数 我们先不管这个标题如何的绕口,也不管委托究竟是个什么东西,来看下面这两个最简单的方法,它们不过是在屏幕上输出一句问候的话语: 以下为引用的内容: public void GreetPeople(string name) { // 做某些额外的事情,比如初始化之类,此处略 EnglishGreeting(name); } public void EnglishGreeting(string name) { Conso le.WriteLine(”Morning, ” name); } 暂且不管这两个方法有没有什么实际意义。GreetPeople用于向某人问好,当我们传递代表某人姓名的name参数,比如说“Jimmy”,进去的时候,在这个方法中,将调用EnglishGreeting方法,再次传递name参数,EnglishGreeting则用于向屏幕输出“Morning, Jimmy”。 现在假设这个程序需要进行全球化,哎呀,不好了,我是人,我不明白“Morning”是什么意思,怎么办呢?好吧,我们再加个中文版的问候方法: 以下为引用的内容: public void ChineseGreeting(string name){ Console.WriteLine(”早上好, ” name); } 这时候,GreetPeople也需要改一改了,不然如何判断到底用哪个版本的Greeting 问候方法合适呢?在进行这个之前,我们最好再定义一个枚举作为判断的依据:以下为引用的内容: view plaincopy to clipboardprint? 1. public enum Language{ 2. English, Chinese 3. }

相关文档
最新文档