C#委托和事件
2016-06-16 11:08
295 查看
其实这部分内容对于 .NET程序员而言应该是老生常谈了,但鉴于团队内常有成员对委托和事件感到混乱,因而记录下来以供分享。
委托是C#第一个版本就引入的特性,特点如下
1. 类似于C++中的函数指针;
2. 允许方法像变量一样赋值;
3. 用以作回调操作;
4. 委托以链表的方式记录委托实例;
5. 委托实例中使用的类型并不需要与委托声明中的类型完全吻合;
6. 在C#2.0中引入了匿名委托,C#3.0引入了Lambda表达式作为委托实例。
通常我们据说的委托包括了委托声明和委托实例两种概念,委托声明是声明了一个委托样式,而委托实例则是与委托声明类型相符的变量,该变量记录了一系列与委托声明形式类似的方法,如
中,public delegate Mammals HandlerMethod()是委托声明,声明HandlerMethod是一种委托类型,任何无参数且无返回值函数都可以被赋值给这种委托类型的实例,例如
HandlerMethod handlerMammals = MammalsHandler;
handlerMammals += DogsHandler;
对委托实例handlerMammals赋值之后,handlerMammals委托列表中记录了两个方法,当用户invoke handlerMammals时,MammalsHandler和DogsHandler方法会依次被调用,而通过handlerMammals-=DogsHandler之类的语句可以对移除委托实例中的委托列表。
通常而言,我们使用到委托是为了实现对象的回调操作,这就要求一个对象实现的委托链表赋值可以在对象外进行操作,但该委托实例的方法列表不能在对象外部被调用, 可以看到通过上述声明和实例化的方式,需要很多代码才能进行这种可见性隔离,此时事件就派上用场了。事件的使用方法如下;
与上一个例子相关不大,但在这个例子中,事件OnMammalHandled作为一个代理,其在类实例之外只允许通过+=/-=方法进行赋值,而在类内等同于完整的委托实例,通过引入事件,可以完美地实现我们需要的回调方法效果,即对外部只具赋值可视性,对内部具有全部可视性。
同样,事件的赋值也可以使用匿名函数或者Lambda表达式,例如
通过强大的委托、事件匿名函数和Lambda表达式等特性,我们可以使回调代码变得清晰简单,并且可读性更高。
委托是C#第一个版本就引入的特性,特点如下
1. 类似于C++中的函数指针;
2. 允许方法像变量一样赋值;
3. 用以作回调操作;
4. 委托以链表的方式记录委托实例;
5. 委托实例中使用的类型并不需要与委托声明中的类型完全吻合;
6. 在C#2.0中引入了匿名委托,C#3.0引入了Lambda表达式作为委托实例。
通常我们据说的委托包括了委托声明和委托实例两种概念,委托声明是声明了一个委托样式,而委托实例则是与委托声明类型相符的变量,该变量记录了一系列与委托声明形式类似的方法,如
class Program { public delegate void HandlerMethod(); public static void MammalsHandler() { } public static void DogsHandler() { } static void Test() { HandlerMethod handlerMammals = MammalsHandler; handlerMammals += DogsHandler; } }
中,public delegate Mammals HandlerMethod()是委托声明,声明HandlerMethod是一种委托类型,任何无参数且无返回值函数都可以被赋值给这种委托类型的实例,例如
HandlerMethod handlerMammals = MammalsHandler;
handlerMammals += DogsHandler;
对委托实例handlerMammals赋值之后,handlerMammals委托列表中记录了两个方法,当用户invoke handlerMammals时,MammalsHandler和DogsHandler方法会依次被调用,而通过handlerMammals-=DogsHandler之类的语句可以对移除委托实例中的委托列表。
通常而言,我们使用到委托是为了实现对象的回调操作,这就要求一个对象实现的委托链表赋值可以在对象外进行操作,但该委托实例的方法列表不能在对象外部被调用, 可以看到通过上述声明和实例化的方式,需要很多代码才能进行这种可见性隔离,此时事件就派上用场了。事件的使用方法如下;
public delegate void HandlerMethod(); class EventTest { public event HandlerMethod OnMammalHandled; public void HandleMammal() { if(null!=OnMammalHandled) OnMammalHandled(); } } static void Test() { EventTest et = new EventTest(); et.OnMammalHandled+=MammalsHandler; et.OnMammalHandled+=DogsHandler; et.HandleMammal(); et.OnMammalHandled-=MammalsHandler; et.OnMammalHandled-=DogsHandler; } public static void MammalsHandler() { } public static void DogsHandler() { }
与上一个例子相关不大,但在这个例子中,事件OnMammalHandled作为一个代理,其在类实例之外只允许通过+=/-=方法进行赋值,而在类内等同于完整的委托实例,通过引入事件,可以完美地实现我们需要的回调方法效果,即对外部只具赋值可视性,对内部具有全部可视性。
同样,事件的赋值也可以使用匿名函数或者Lambda表达式,例如
static void Test() { EventTest et = new EventTest(); et.OnMammalHandled+=delegate(){}; et.OnMammalHandled+=()=>{}; et.HandleMammal(); }
通过强大的委托、事件匿名函数和Lambda表达式等特性,我们可以使回调代码变得清晰简单,并且可读性更高。
相关文章推荐
- 如何在 Linux/Windows/MacOS 上使用 .NET 进行开发
- c#调用COM组件
- 如何在 Linux 中安装微软的 .NET Core SDK
- C#实现把指定数据写入串口
- C#动态创建button的方法
- C#中抽象方法与虚拟方法的区别
- c#中虚函数的相关使用方法
- C#实现给图片加水印的方法
- C#使用加边法计算行列式的值
- C#实现多线程的同步方法实例分析
- jQuery中的常用事件总结
- C#中尾递归的使用、优化及编译器优化
- C#中的delegate委托类型基本学习教程
- C#实现子窗体与父窗体通信方法实例总结
- C#通用邮件发送类分享
- 举例讲解C#中自动实现的属性
- C#中this的用法集锦
- C#数据结构之顺序表(SeqList)实例详解
- C#.NET获取拨号连接的宽带连接方法
- RabbitMQ入门与使用篇 推荐