.NET简谈组件程序设计之(delegate与event关系)

简介:

本人最近一段时间在学习关于.NET组件编程方面的技术,在学习过程中确实有很多好的东西需要与大家分享。[王清培版权所有,转载请给出署名]

关于什么叫组件编程,其实就是利用.NET来开发基于组件模型的程序,面向组件编程而非面向对象编程,这是一个高度,没有很长时间的学习与磨练

是体会不到这个感觉的。我们现在的开发思想应该是以面向对象为主的,但是如何提升这个高度,只有慢慢的学习了。

其实面向组件编程包含了面向对象编程思想,将一组功能独立的封装起来供以后重复使用,但是在开发组件的过程中需要使用到面向对象的思想来构

造组件,这两个概念不矛盾,面向对象思想是具体实现,而面向组件思想应该说是站在一个产品或者说是一个框架的高度来宏观的形容。

这些技术哲学我们就不讨论了,学点实际的东西比较现实。我们只需要知道,面向对象编程是代码重用,而面向组件编程是实现的重用。而不管是面

向对象也好还是面向组件也好,归根到底都得用良好的代码来实现。只要我们在开始编码的时候,在脑海里注入这些需要考虑的想法后就可以了。

这篇文章我们先来扫除组件编程中经常用到的委托与事件的一些技术疑惑。在没有学习组件编程之前,我也是不能理解delegate与event的关系和两

者之间到用意何在。但是在最近的学习过程中以有了大概的了解,并且决定写出学习到的技术与大家分享。[王清培版权所有,转载请给出署名]


delegate在C#中表示委托的概念,而event表示事件的概念,但是这两者之间为什么需要结合起来使用,不用event也能很好的实现面向对象中的事件

的思想和功能,通过多播委托一样可以调用所有订阅者。

其实要说为什么需要用event来使用事件的机制,一句话就概括了,但是我这里先不说,说了就没啥意思了,请继续看。


我们先来看点代码:

1:

 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4.  
  5. namespace EventDemo  
  6. {  
  7.     /// <summary>  
  8.     /// 句柄移除委托  
  9.     /// </summary>  
  10.     /// <param name="handle">提示信息</param>  
  11.     public delegate void MoveHandler(string handle);  
  12.     /// <summary>  
  13.     /// 句柄对象  
  14.     /// </summary>  
  15.     public class ObjectHandler  
  16.     {  
  17.         /// <summary>  
  18.         /// 句柄事件  
  19.         /// </summary>  
  20.         public MoveHandler hand;  
  21.         /// <summary>  
  22.         /// 触发句柄事件通知所有订阅者  
  23.         /// </summary>  
  24.         public void Onhand()  
  25.         {  
  26.             hand("句柄事件");  
  27.         }  
  28.     }  
  29. }  

2:

 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4.  
  5. namespace EventDemo  
  6. {  
  7.     class Program  
  8.     {  
  9.         static void Main(string[] args)  
  10.         {  
  11.             ObjectHandler handermanager = new ObjectHandler();  
  12.             handermanager.hand += handmethod;  
  13.             handermanager.Onhand();  
  14.         }  
  15.         public static void handmethod(string eventstring)  
  16.         {  
  17.             Console.WriteLine(eventstring);  
  18.             Console.ReadLine();  
  19.         }  
  20.     }  
  21. }  


为了演示效果,我随便起了个对象名称,没有什么特殊意义。


我定义了一个ObjectHandler对象,在内部使用MoveHandler委托实例表示事件对象,当调用Onhand方法的时候我通过委托实例来逐一的调用订阅者来达到事件的效果。但是一般不回将触发事件的方法定义成公共的,这里只是为了显示。

[王清培版权所有,转载请给出署名]
我们引入问题,事件是属于对象内部私有的,只能由对象来触发事件才符合面向对象规则,但是光使用委托无法达到目的。委托实例需要被订阅者订阅才行,那么委托实例必须是公共的,这个时候委托就不可能保证是谁触发了事件。
请看代码:

3:

 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4.  
  5. namespace EventDemo  
  6. {  
  7.     class Program  
  8.     {  
  9.         static void Main(string[] args)  
  10.         {  
  11.             ObjectHandler handermanager = new ObjectHandler();  
  12.             handermanager.hand += handmethod;  
  13.             handermanager.Onhand();  
  14.  
  15.             /*我通过触发对象内部的委托,来蒙骗所有订阅者。  
  16.             订阅者都认为是ObjectHandler发出的事件,其实是有人偷偷的模拟事件。*/ 
  17.             handermanager.hand("借刀杀人");  
  18.         }  
  19.         public static void handmethod(string eventstring)  
  20.         {  
  21.             Console.WriteLine(eventstring);  
  22.             Console.ReadLine();  
  23.         }  
  24.     }  
  25. }  

订阅者没有任何理由来承担这个意外的责任,ObjectHandler对象必须为此承担责任。

那么如何避免事件不被恶意者触发呢,那么这个是就需要event关键字了,如果用event修饰过后的委托实例,是无法在对象的外部被触发的。请看代码:

4:

 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4.  
  5. namespace EventDemo  
  6. {  
  7.     /// <summary>  
  8.     /// 句柄移除委托  
  9.     /// </summary>  
  10.     /// <param name="handle">提示信息</param>  
  11.     public delegate void MoveHandler(string handle);  
  12.     /// <summary>  
  13.     /// 句柄对象  
  14.     /// </summary>  
  15.     public class ObjectHandler  
  16.     {  
  17.         /// <summary>  
  18.         /// 句柄事件  
  19.         /// </summary>  
  20.         public event MoveHandler hand;  
  21.         /// <summary>  
  22.         /// 触发句柄事件通知所有订阅者  
  23.         /// </summary>  
  24.         public void Onhand()  
  25.         {  
  26.             hand("句柄事件");  
  27.         }  
  28.     }  
  29. }  


这样就很好的维护了对象的封闭原则。




 本文转自 王清培 51CTO博客,原文链接:http://blog.51cto.com/wangqingpei557/639337,如需转载请自行联系原作者

相关文章
|
1天前
|
前端开发 C# 数据库
.NET中使用BootstrapBlazor组件库Table实操篇
.NET中使用BootstrapBlazor组件库Table实操篇
|
1天前
|
开发框架 前端开发 .NET
七天.NET 8操作SQLite入门到实战 - (1)第七天BootstrapBlazor UI组件库引入
七天.NET 8操作SQLite入门到实战 - (1)第七天BootstrapBlazor UI组件库引入
|
1天前
|
搜索推荐 API C#
.NET开源快速、强大、免费的电子表格组件
.NET开源快速、强大、免费的电子表格组件
|
1天前
|
SQL 开发框架 JavaScript
分享33个ASP.NET电子商务源码和40个ASP.NET控件组件源码,总有一款适合您
分享33个ASP.NET电子商务源码和40个ASP.NET控件组件源码,总有一款适合您
32 0
|
1天前
|
SQL 数据库 开发工具
“.NET视频总结:认识框架的结构和组件,掌握开发工具的奥妙“
“.NET视频总结:认识框架的结构和组件,掌握开发工具的奥妙“
56 0
|
6月前
|
编解码 JSON 算法
一个支持.Net 7的WinForm开源UI组件框架
一个支持.Net 7的WinForm开源UI组件框架
92 0
|
1天前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
47 0
|
1天前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
22 0
|
1天前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
32 0