重读C#委托、事件有感
去年学习C#的时候按照进度把C#的委托和事件“认真”的学习了一下,自己知道委托和事件的重要性,所以也努力的学习,可说实也没怎么学懂。碰巧这段时间在做一个解析GPS数据的小项目,因为其中有需要条件自动判断并处理的模块,因此首先想到的就是委托和事件。借此机会重新学习和复习了一下,收获颇丰。
什么是委托?根据我的理解委托就是把一件可能发生的事情,当满条件达到时委托别人帮忙处理。根据从书上看到的委托应该是有C++的函数指针发展而来的,只不过C#中一般不用指针。在这里举一个小例子,输入一个字符串当它的长度满足指定长度时输出,达到指定长度就是触发了事件。
class AutoDisposeStr
{
public AutoDisposeStr(int length)
{
LimitLength = length;
}
public delegate void DisplaysrtHandler();
public DisplaysrtHandler MeetLength;
public void OnReadAndDisplay()
{
Console.WriteLine(str);
}
public DisplaysrtHandler MeetLength
{
get { return _MeetLength; }
set { _MeetLength = value; }
}
public int LimitLength
{
get { return _LimitLength; }
set { _LimitLength = value; }
}
public string str
{
get { return _str; }
set
{
if (value.Length >= LimitLength)
{
_str = value;
MeetLength();
}
}
}
private int _LimitLength;
private string _str;
private DisplaysrtHandler _MeetLength;
}
}
首先构建了一AutoDisposeStr类有三个字段_LimitLength表示处理字符串的门限值对应的属性为LimitLength,_Str将要处理的字符串对应属性为Str,_MeetLength为委托类型的字段对应属性为MeetLength用来注册监听者。需要注意的是委托类型参数列表和你处理函数的参数列表需要对应,在这里就是 public delegate void DisplaysrtHandler()和public void OnReadAndDisplay()。因为要实时监听字符串长度是否达到门限值,所以要在字符串属性赋值时进行处理。每输入一个字符串,判断长度是否达到门限值,如果达到则调用监听函数处理:
public string str
{
get { return _str; }
set
{
if (value.Length >= LimitLength)
{
_str = value;
MeetLength();//调用监听函数处理
}
}
在这里其实就是把处理的方法委托给了public void OnReadAndDisplay()函数。最后只需要在Main()函数中实例化并注册监听函数即可。委托的用法就这么简单,不过有几点组要注意:
一:如果当前没有订阅者也就是MeetLength为空执行 MeetLength()会引发异常NullReferenceException,因此为了解决这个问题在触发事件之前检查空值。
DisplaysrtHandler local=MeetLength;
if(local!=null)
{
local();
}
这里定义了一个局部变量来检查是否为空是为了防止来自不同线程订阅者被移除可能造成NullReferenceException异常,因为MeetLength-=<listener>,会将一个全新的委托指派给MeetLength,这不会对原先local委托有任何影响。
二,委托链会按注册的顺序调用,但是如果一旦前面的委托发生异常,后面的委托将得不到执行。因此最保险的方法应该用foreach(DisplaysrtHandler myhander in local.GetInvocationList){}同时加上异常处理。
委托就说这么多吧,说的不对的地方欢迎指正共同学习。
接下来说说事件,我感觉事件就是在委托的基础上增加了一些编程的规范。对于委托你可以在任何包容类之外调用委托,这就会造成对包容类内委托结果的影响。不满足封装性要求,其次事件中当注册事件和移除事件时如果不幸将“-=”或“+=”写成了“=”在委托中没有语法错误而是造成了委托连被无意赋值号覆盖掉了,而在事件中这样的大意是不能编译通过的。防止了这种错误的可能性,还有事件中对事件处理函数参数有规范要求,这里就不多讲了。贴上事件的代码以做对比:
class AutoDisposeStr
{
public class AutoDisposeStrArgs : System.EventArgs
{ }
public AutoDisposeStr(int length)
{
LimitLength = length;
}
public delegate void DisplaysrtHandler(object sender, AutoDisposeStrArgs newAutoDisposeStr);
public event DisplaysrtHandler MeetLength;
public void OnReadAndDisplay(object sender, AutoDisposeStrArgs newAutoDisposeStr)
{
Console.WriteLine(str);
}
//public DisplaysrtHandler MeetLength
//{
// get { return _MeetLength; }
// set { _MeetLength = value; }
//}
public int LimitLength
{
get { return _LimitLength; }
set { _LimitLength = value; }
}
public string str
{
get { return _str; }
set
{
if (value.Length >= LimitLength)
{
_str = value;
MeetLength(this,null);
}
}
}
private int _LimitLength;
private string _str;
//private DisplaysrtHandler _MeetLength;
}
主函数:
class Program
{
static void Main(string[] args)
{
AutoDisposeStr ads= new AutoDisposeStr(5);
ads.MeetLength += ads.OnReadAndDisplay;
for (int i = 0; i < 10; i++)
{
ads.str = Console.ReadLine();
}
}
本人也是初学者,有说的不对不妥的地方欢迎指正,共同学习,共同进步。
重读C#委托、事件有感的更多相关文章
- C# ~ 从 委托事件 到 观察者模式 - Observer
委托和事件的部分基础知识可参见 C#/.NET 基础学习 之 [委托-事件] 部分: 参考 [1]. 初识事件 到 自定义事件: [2]. 从类型不安全的委托 到 类型安全的事件: [3]. 函数指针 ...
- C#委托,事件理解入门 (译稿)
原文地址:http://www.codeproject.com/Articles/4773/Events-and-Delegates-Simplified 引用翻译地址:http://www.cnbl ...
- 关于ios使用jquery的on,委托事件失效
$('.parents').on("click",'.child',function(){}); 类似上面这种,在ios上点击"child"元素不会起作用,解决 ...
- Observer设计模式中-委托事件-应用在消息在窗体上显示
Observer设计模式:监视者模式.在类中的方法中处理的结果或者消息通过事件委托 的方式发送给主窗体. 因为在其它类中直接访问主窗体类,显示内容是不能直接调用控件赋值的,当然也有别的类似查阅控件名, ...
- Asp.net用户控件和委托事件
在Asp.net系统制作过程中,门户类型的网站,我们可以用DIV+CSS+JS+Ajax全部搞定,但是一旦遇到界面元素比较复杂的时候,还是UserControl比较方便一些,各种封装,各种处理,然后拖 ...
- jQuery里面的普通绑定事件和on委托事件
以click事件为例: 普通绑定事件:$('.btn1').click(function(){}绑定 on绑定事件:$(document).on('click','.btn2',function(){ ...
- c#基础学习笔记-----------委托事件
这里有一个比较简单的委托实例应用(跨窗体操作控件) http://blog.csdn.net/bdstjk/article/details/7004035 还有一个比较详细的介绍并深入理解委托事件的讲 ...
- c#委托事件入门--第二讲:事件入门
上文 c#委托事件入门--第一讲:委托入门 中和大家介绍了委托,学习委托必不可少的就要说下事件.以下思明仍然从事件是什么.为什么用事件.怎么实现事件和总结介绍一下事件 1.事件是什么:. 1.1 NE ...
- Unity C#笔记 委托&事件
C#的委托与事件搭配,即是观察者模式的一种实现. 因为观察者模式的原理很易懂,不作多讲,本文纯粹用于记录语法. delegate(委托) //声明没有参数,没有返回值的委托类型XXXX public ...
- JavaScript中事件委托(事件代理)详解
在JavaScript的事件中,存在事件委托(事件代理),那么什么是事件委托呢? 事件委托在生活中的例子: 有三个同事预计会在周一收到快递.为签收快递,有两种办法:一是三个人在公司门口等快递:二是委托 ...
随机推荐
- mongoDB在centos7上的安装
1,下载安装包 下载MongoDB的安装文件 地址:https://www.mongodb.org/downloads#production 选择Linux 64-bit legacy 版本,下载到目 ...
- AngularJs $animate 让页面动起来
$animate $animate服务提供了基本的DOM操作功能如在DOM里插入.移除和移动元素,以及添加和删除类.这个服务是ngAnimate的核心服务,为CSS和Javascript提供了高档次的 ...
- HDU 5904 LCIS (最长公共上升序列)
传送门 Description Alex has two sequences a1,a2,...,an and b1,b2,...,bm. He wants find a longest common ...
- UVA11136Hoax or what( multiset的应用)
题目链接 题意:n天,每天往一个箱子里放m个数,放完之后取最大的Max和最小的min做差,并把这两个数去掉,求n天之后的和 multiset 和 set的原理是相似的,multiset可以存多个相同的 ...
- 支持向量机(SVM)入门
一.简介 支持向量机,一种监督学习方法,因其英文名为support vector machine,故一般简称SVM. 通俗来讲,它是一种二类分类模型,其基本模型定义为特征空间上的间隔最大的线性分类器, ...
- liunx 的 grep命令(转载)
简介 grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它 ...
- IP-Address TextBox
http://www.codeproject.com/Articles/4693/IP-Address-TextBox 可以下载试用效果.个人感觉功能很强大,但输入时让人不太舒服.可以参考. ntro ...
- Java数据结构——队列
//================================================= // File Name : Queue_demo //-------------------- ...
- Could not load file or assembly Microsoft.Web.Infrastructure
Error info:Could not load file or assembly 'Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=n ...
- SSLv3 Poodle攻击漏洞检测工具
漏洞编号:CVE-2014-3566 POC如下: import ssl,socket,sys SSL_VERSION={ 'SSLv2':ssl.PROTOCOL_SSLv2, 'SSL ...