解惑答疑:C#委托和事件

  相信很多人一直为C#委托和事件所困惑,尤其是C#的初学者,学到这一部分会感觉比较困难,很有可能就放弃了,而且.NET对委托和事件封装得挺好,一般都不怎么用到自定义的委托和事件,所以放弃学习该技术就有了借口!

  网上也有不少此类的文章,最具代表性的是张子阳的C#中的委托和事件这篇,写得的确很好,得到很多读者的赞赏,但我看评论,还是发现了些问题,因为有不少读者是看了一遍又一遍,每次感觉都蛮好,可是隔一段时间,对“委托和事件”又迷糊了,于是又来看!我真搞不懂,为什么会出现这种情况!后来想想,文章虽好,但总结的地方没有把重点列出来;再者,读者跟着作者的思路,的确能把文章看懂,但是读者自己不得要领,没有真正弄明白,因此就出现了上面提到的状况!

  C#委托和事件真的难吗,其实不然。要搞懂它,第一,要看你的理解能力;第二,要看你怎么理解它。如果你觉得理解起来比较困难,那我们可以换种理解方式,也许能很好地理解它了!其实委托和事件的确不难,大牛级别的甚至都不屑写此类文章!

  为什么会有委托?

  委托其实就是个方法指针,拥有同样参数和返回值的任何方法都能传给委托;委托能够消除条件分支语句,不需要根据if、case这些语句来判断具体调用哪个方法!而委托又是从观察者模式演化而来,这里推荐阅读TerryLee的这篇观察者模式文章。  

  前面说的的就算不理解也不要紧,关键是理解方法、委托、事件之间的关系。可以这样说,方法是“委托”给委托的,而委托是“委托”给事件的。可以将事件看成是委托的一个容器,里面可以加一连串的委托!这样来理解,那所有的事情就都解决了!

  当然,我们都是在某个方法中触发事件,事件将其交给委托,委托再交给方法,方法再进行实际的操作,与上面的步骤刚好相反!其实触发事件的目的就是触发具体方法!

  再来说说委托的好处(上面没举例子),比如你开发了一个电子商务平台,后台有管理商品的功能,而商品信息有七八列或者更多,包括编号、商品名称、价格、上架时间等等,该信息又能根据任意一列来进行排序!如果没有委托,我们将根据点击某列所产生的信息,将这信息传给某个排序方法,而这个排序方法会接受传来的信息作为参数,再根据内部的分支语句if、case等来判断具体采用哪个排序方法,这样的话,逻辑变复杂,这过程当中还要做很多无用功(因为很有可能要进行多次判断才能找到要真正执行的方法),而且如果我们将来再增加列,又得增加分支语句,违背了“开放—封闭”原则,维护起来比较麻烦!有了委托,我们不需要传递任何参数,直接将具体方法传给委托即可,增加列则只要增加一个新方法,爽!我们完全可以通过委托来调用方法,那为什么还要事件呢?事件其实是对委托进行一种限制,使其无法使用“=”赋值运算符(如果使用则在编译时产生错误),只能使用“+=”或者“-=”运算符,这就防止了程序员误将原先的委托链给覆盖掉,另外delegate类从MulticastDelegate(多路广播委托)继承而来,所以可以将多个委托赋给同一个事件!

  最后,列一串代码把上面的概念理清一下

class Program

{

static void Main(string[] args)

{

 XiaoBai xiaobai = new XiaoBai();

//Google公司

ItCompany google = new ItCompany("谷歌中国", "CTO", xiaobai);

//微软公司

ItCompany microsoft = new ItCompany("微软中国", "架构师", xiaobai);

//花旗银行

FinanceCompany AmericaBank = new FinanceCompany("花旗银行", "金融分析师", xiaobai);

//委托的好处,可以应用于不同的类的不同方法

//方法“委托”给委托,委托“委托”给事件

//委托类型与事件声明时的委托类型相同

//因为是传引用,所以方法后面不能带括号,带括号则是调用方法了

//一个委托可以搭载多个方法,一个事件则拥有一个委托链

xiaobai.Update += new TheEventHandler(google.ComeToItCompany);

xiaobai.Update += new TheEventHandler(microsoft.ComeToItCompany);

xiaobai.Update += new TheEventHandler(AmericaBank.ComeToFinanceCompany);

xiaobai.SubjectState = "我小白过来应聘职位啦!";

//发出通知,触发事件

xiaobai.Notify();

//以下代码与上面相似

XiaoHua xiaohua = new XiaoHua();

ItCompany microsoft2 = new ItCompany("微软总公司", "CEO", xiaohua);

FinanceCompany ChinaBank = new FinanceCompany("中国央行", "财务部总经理", xiaohua);

xiaohua.Update += new TheEventHandler(microsoft2.ComeToItCompany);

xiaohua.Update += new TheEventHandler(ChinaBank.ComeToFinanceCompany);

xiaohua.SubjectState = "我小华过来应聘职位啦!";

xiaohua.Notify()

Console.ReadLine();

}

}

//通知者接口

interface Subject

{

void Notify();

string SubjectState

{

get;

set;

}

}

 //事件处理程序的委托,相当
于一个类(在编译成IL后确确实实是类)或者方法指针,

与常规类定义不同,带参数和返回值

delegate void TheEventHandler();

//小白

class XiaoBai : Subject

{

//声明一事件Update,类型为委托TheEventHandler

public event TheEventHandler Update;

private string action; //用Notify方法触发事件

public void Notify()

{

Update();

}

public string SubjectState

{

get { return action; }

set { action = value; }

}

}

//小华

class XiaoHua : Subject

{

//声明一事件Update,类型为委托TheEventHandler

public event TheEventHandler Update;

private string action;

//用Notify方法触发事件

public void Notify()

{

Update();

}

public string SubjectState

{

get { return action; }

set { action = value; }

}

}

//IT行业

class ItCompany

{

private string companyname;

private string job;

private Subject sub;

public ItCompany(string _companyname, string _job, Subject _sub)

{

companyname = _companyname;

job = _job;

sub = _sub;

}

//参数和返回值与委托TheEventHandler一致

public void ComeToItCompany()

{

Console.WriteLine("{0} {1}: 来我们公司做{2}!", sub.SubjectState,

companyname, job);

}

}

//金融行业

class FinanceCompany

{

private string companyname;

private string job;

private Subject sub;

public FinanceCompany(string _companyname, string _job, Subject _sub)

{

companyname = _companyname;

job = _job;

sub = _sub;

}

//参数和返回值与委托TheEventHandler一致

public void ComeToFinanceCompany()

{

Console.WriteLine("{0} {1}: 来我们公司做{2}!", sub.SubjectState,

companyname, job);

}

}

  通过以上总结,我相信大家对C#委托和事件应该可以更好地理解了!当然,委托的知识不止这些,还会用到检查空值、异常处理和多线程处理等等,这篇文章仅在解惑(我也不高兴浪费太多的时间来具体讲解)!如果你想更好地掌握委托和事件,可以看下上面提到的张子阳的两篇文章或者买本《C#本质论》仔细研读;如果你想了解观察者模式,可以看下上面提到的TerryLee那篇文章;如果你还没有学习设计模式或者刚刚开始学习,我建议阅读《大话设计模式》;如果你学习设计模式有一段时间了,我建议阅读《设计模式:基于C#的工程化实现及扩展》!祝各位程序员好运!

时间: 2024-09-04 10:49:47

解惑答疑:C#委托和事件的相关文章

艾伟_转载:解惑答疑:C#委托和事件

相信很多人一直为C#委托和事件所困惑,尤其是C#的初学者,学到这一部分会感觉比较困难,很有可能就放弃了,而且.NET对委托和事件封装得挺好,一般都不怎么用到自定义的委托和事件,所以放弃学习该技术就有了借口! 网上也有不少此类的文章,最具代表性的是张子阳的C#中的委托和事件这篇,写得的确很好,得到很多读者的赞赏,但我 看评论,还是发现了些问题,因为有不少读者是看了一遍又一遍,每次感觉都蛮好,可是隔一段时间,对"委托和事件"又迷糊了,于是又来看!我真搞不懂,为什 么会出现这种情况!后来想想

从反射看委托与事件 委托真的是一个类

关于委托与事件,网上介绍得非常之多,在此不再赘述,本人最近需要捣鼓一些委托,因而对委托进行一 定的寻根究底,故用反射把委托的成员揪出来,且看如下代码: delegate void DelegateDemo(); static event DelegateDemo delHandle; static void Main() { delHandle += new DelegateDemo(MyDelegate_delHandle); MemberInfo[] mis = delHandle.GetT

C#委托和事件

委托和事件 .NET Framework 还可以广泛地将委托用于事件处理任务,如 Windows 或 Web 应用程序中的按钮 Click 事件.Java 中的事件处理通常通过实现自定义侦听器类完成,而 C# 开发人员则可以利用委托处理事件.事件的声明类似于具有委托类型的字段,区别在于事件声明前面有 event 关键字.事件通常被声明为 public,但允许使用任何可访问性修饰符.下面的示例演示了 delegate 和 event 的声明. C#  =复制代码 // Declare the de

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

一. 问题引入          通常,一个C语言学习者登堂入室的标志就是学会使用了指针,而成为高手的标志又是"玩转指针".指针是如此奇妙,通过一个地址,可以指向一个数,结构体,对象,甚至函数.最后的一种函数,我们称之为"函数指针"(和"指针函数"可不一样!)就像如下的代码: int func(int x); /* 声明一个函数 */ int (*f) (int x); /* 声明一个函数指针 */ f=func; /* 将func函数的首地址赋

C#中委托,事件理解入门

目录 l        导论 l        什么是委托 l        事件的理解 l        事件 关键字 l        最后     导论     在学习C#中的委托和事件过程中,我读了许多文章来理解他们二者究竟是怎么一回事,以及如何使用他们,现在我将整个的理解过程陈述以下,我学到的每一方面,恐怕也是你们需要掌握的 :-). 什么是委托?     委托和事件这两个概念是完全配合的.委托仅仅是函数指针,那就是说,它能够引用函数,通过传递地址的机制完成.委托是一个类,当你对它实例

C#编程利器之四:委托与事件(Delegate and event) (上)

本文试图在.net Framework环境下,使用C#语言来描述委托.事件的概貌.希望本文能有助于大家理 解委托.事件的概念,理解委托.事件的用途,理解它的C#实现方法,理解委托与事件为我们带来的好处 .C#是一种新的语言,希望大家能通过本文清楚地看到这些,从而可以对委托.事件等技术进行更深入的 理解和探索. 一. 委托 委托的本质 --在C#中,委托是一个特殊的类: --在某种程度上,相当于C++的函数指针: --在某种程度上,相当于接口(Interface): 委托的定义 --关键字:del

C#3.0笔记(二)预备知识之委托与事件

在上篇blog中简单地介绍了委托的基础知识,在这片文章中会介绍下委托跟 事件之间的联系. 事件的由来 我们可以看到在使用委托进行回调 的实现的时候,我们往往需要再定义一个委托对象,以及一个对外公开的辅助方 法来添加委托的方法,这样子会使我们感觉比较繁琐.C#提供了event关键字来 减轻直接使用委托的负担,编译器会自动提供注册.取消注册的方法和委托必要 的成员.首先来看看定义事件的步骤: 1.先定义委托类型: 2.通 过event关键字定委托类型的事件. public delegate int

C#----委托和事件(一)

什么是委托 委托怎么用 定义委托类型 声明委托对象 创建委托对象确定与哪些方法进行绑定 使用委托调用方法 使用委托注意事项 为什么用委托 总结      最近在做的项目,正在进行重构,之前的框架就是纯三层的简单调用,外加一些Session,SQLHelper等封装管理类,其他的东西,一直也想去抽象,但是奈何能力还有所欠缺,抽象出来的东西,被组长狠狠的给鄙视了一番,最近在组长的带领下,重新搭建框架,整个过程下来,真的是被狠狠的打击了,也真是服了我们组长了,太牛了,看来自己欠缺的还是很多很多.具体的

编写高质量代码改善C#程序的157个建议[C#闭包的陷阱、委托、事件、事件模型]

原文:编写高质量代码改善C#程序的157个建议[C#闭包的陷阱.委托.事件.事件模型] 前言 本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html .本文主要学习记录以下内容: 建议38.小心闭包中的陷阱 建议39.了解委托的实质 建议40.使用event关键字对委托施加保护 建议41.实现标准的事件模型 建议38.小心闭包中的陷阱 首先我们先来看一段代码: class Program { static void Main(string[] arg