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

简介:   相信很多人一直为C#委托和事件所困惑,尤其是C#的初学者,学到这一部分会感觉比较困难,很有可能就放弃了,而且.NET对委托和事件封装得挺好,一般都不怎么用到自定义的委托和事件,所以放弃学习该技术就有了借口!  网上也有不少此类的文章,最具代表性的是张子阳的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#的工程化实现及扩展》!祝各位程序员好运!

目录
相关文章
|
24天前
|
C#
C#一分钟浅谈:委托与事件的实现方式
本文详细介绍了C#编程中委托与事件的基础知识及应用场景。首先解释了委托的概念,包括定义与使用方法;接着介绍了事件这一基于委托的特殊类型,展示了如何在类中定义事件及跨类订阅与处理事件;最后讨论了常见问题如事件未处理异常、重复订阅及内存泄漏等,并提出了相应的解决方案。通过本文,读者将全面掌握委托与事件的使用技巧,提升应用程序的设计与开发水平。
54 7
|
2月前
|
C#
由浅入深理解C#中的事件
由浅入深理解C#中的事件
100 19
|
2月前
|
图形学 C# 开发者
全面掌握Unity游戏开发核心技术:C#脚本编程从入门到精通——详解生命周期方法、事件处理与面向对象设计,助你打造高效稳定的互动娱乐体验
【8月更文挑战第31天】Unity 是一款强大的游戏开发平台,支持多种编程语言,其中 C# 最为常用。本文介绍 C# 在 Unity 中的应用,涵盖脚本生命周期、常用函数、事件处理及面向对象编程等核心概念。通过具体示例,展示如何编写有效的 C# 脚本,包括 Start、Update 和 LateUpdate 等生命周期方法,以及碰撞检测和类继承等高级技巧,帮助开发者掌握 Unity 脚本编程基础,提升游戏开发效率。
40 0
|
2月前
|
编译器 C#
C#中内置的泛型委托Func与Action
C#中内置的泛型委托Func与Action
50 4
|
2月前
|
C#
C#中的委托(一)
C#中的委托(一)
33 1
|
2月前
|
存储 算法 安全
C#语言进阶(二)—事件全解
C#语言进阶(二)—事件全解
30 0
|
2月前
|
C# C++
C#语言进阶(一)—委托
C#语言进阶(一)—委托
40 0
|
5月前
|
存储 安全 C#
C# - 委托与事件
这篇文档介绍了C#中的委托和事件。委托是存储方法引用的类型,支持回调、事件处理,具有引用方法、类型安全、多播性等特性,并在异步编程中发挥作用。事件是委托的封装,提供保护和订阅机制,防止外部直接访问。当需要在类内部控制方法调用,防止外部误触发时,可使用事件。
|
4月前
|
C#
C#||委托和事件的实例
C#||委托和事件的实例
|
5月前
|
C#
c#委托详解
c#委托详解
30 0