.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,如需转载请自行联系原作者

相关文章
|
6月前
|
前端开发 C# 数据库
.NET中使用BootstrapBlazor组件库Table实操篇
.NET中使用BootstrapBlazor组件库Table实操篇
169 0
|
6月前
|
开发框架 前端开发 .NET
七天.NET 8操作SQLite入门到实战 - (1)第七天BootstrapBlazor UI组件库引入
七天.NET 8操作SQLite入门到实战 - (1)第七天BootstrapBlazor UI组件库引入
|
24天前
.NET 4.0下实现.NET4.5的Task类相似功能组件
【10月更文挑战第29天】在.NET 4.0 环境下,可以使用 `BackgroundWorker` 类来实现类似于 .NET 4.5 中 `Task` 类的功能。`BackgroundWorker` 允许在后台执行耗时操作,同时不会阻塞用户界面线程,并支持进度报告和取消操作。尽管它有一些局限性,如复杂的事件处理模型和不灵活的任务管理方式,但在某些情况下仍能有效替代 `Task` 类。
|
6月前
|
搜索推荐 API C#
.NET开源快速、强大、免费的电子表格组件
.NET开源快速、强大、免费的电子表格组件
104 0
|
4月前
|
存储 开发框架 前端开发
基于Lumisoft.NET组件,使用IMAP协议收取邮件
基于Lumisoft.NET组件,使用IMAP协议收取邮件
|
4月前
|
存储 对象存储 Python
`openpyxl`是一个用于读写Excel 2010 xlsx/xlsm/xltx/xltm文件的Python库。它不需要Microsoft Excel,也不需要.NET或COM组件。
`openpyxl`是一个用于读写Excel 2010 xlsx/xlsm/xltx/xltm文件的Python库。它不需要Microsoft Excel,也不需要.NET或COM组件。
|
5月前
|
NoSQL 大数据 Redis
分享5款.NET开源免费的Redis客户端组件库
分享5款.NET开源免费的Redis客户端组件库
|
2月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
41 7
|
2月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
59 0
|
3月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
48 0