重读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的事件中,存在事件委托(事件代理),那么什么是事件委托呢? 事件委托在生活中的例子: 有三个同事预计会在周一收到快递.为签收快递,有两种办法:一是三个人在公司门口等快递:二是委托 ...
随机推荐
- AngularJs $interval 和 $timeout
$interval window.setInterval的Angular包装形式.Fn是每次延迟时间后被执行的函数. 间隔函数的返回值是一个承诺.这个承诺将在每个间隔刻度被通知,并且到达规定迭代次数后 ...
- Java垃圾收集学习笔记
(1)除了释放不再被引用的对象,垃圾收集器还要处理 堆碎块 .请求分配新对象时可能不得不增大堆空间的大小,虽然可以使用的空闲空间是足够的,但是堆中没有没有连续的空间放得下新对象.可能会导致虚拟机产生不 ...
- System.IO.Directory.Delete目录删除
在程序运行的时候,如果直接获取一个目录路径,然后执行删除(包括子目录及文件): System.IO.Directory.Delete(path,true); 或者 System.IO.Director ...
- java校验时间格式 HH:MM
package com; import java.text.SimpleDateFormat; import java.util.Date; /** * @author Gerrard */ publ ...
- 在JavaScript中,arguments是对象的一个特殊属性。
arguments对象 function函数的内置参数的"数组"/"集合":同时arguments对象就像数组,但是它却不是数组. 常用属性: 1.length ...
- Win7 配置Apache+PHP+Mysql环境
第一.安装并配置APACHE(安装到D:\phpapache\Apache2.2) 1.安装时默认安装,Network Domain, Server Name 我填写我的计算机名,Administra ...
- JavaScript学习笔记——事件
javascript事件基础和事件绑定 一.事件驱动 1.事件 javascript侦测到的用户的操作或是页面的一些行为(怎么发生的) 2.事件源 引发事件的元素.(发生在谁的身上)3.事件处理程序 ...
- netcat命令
1 简介 netcat是网络工具中的瑞士军刀,它能通过TCP和UDP在网络中读写数据.通过与其他工具结合和重定向,你可以在脚本中以多种方式使用它.使用netcat命令所能完成的事情令人惊讶. netc ...
- texlive2015+texstudio
编译器 texlive2015 编辑器 texstudio
- Which is the best opencv or matlab for image processing?
http://www.researchgate.net/post/Which_is_the_best_opencv_or_matlab_for_image_processing Annette Mor ...