我们写一个类时,有时候会在同一个类上添加很多事件,事件很多的话,是不容易管理的,.NET提供的EventHandlerList可以辅助多个事件的管理,但不方便的地方是,它不是类型安全的,缺少类型安全,多少用起来担心会出错。经过我的一番改造,可以将系统提供的EventHandlerList通过泛型提供类型安全的管理。泛型类EventHandlerList.cs的实现如下:

 public sealed class EventHandlerList<T> : IDisposable
{
ListEntry head; public EventHandlerList()
{ } public Delegate this[T key]
{
get{
ListEntry e = Find(key);
return e == null ? null : e.m_handler;
}
set{
ListEntry e = Find(key);
if (e != null){
e.m_handler = value;
}
else {
head = new ListEntry(key, value, head);
}
}
} public void AddHandler(T key, Delegate value)
{
ListEntry e = Find(key);
if (e != null) {
e.m_handler = Delegate.Combine(e.m_handler, value);
}
else {
head = new ListEntry(key, value, head);
}
} public void AddHandlers(EventHandlerList<T> listToAddFrom)
{
ListEntry currentListEntry = listToAddFrom.head;
while (currentListEntry != null) {
AddHandler(currentListEntry.m_key, currentListEntry.m_handler);
currentListEntry = currentListEntry.m_next;
}
} public void Dispose()
{
head = null;
} private ListEntry Find(T key)
{
ListEntry found = head;
while (found != null) {
if (found.m_key.Equals(key)) {
break;
}
found = found.m_next;
}
return found;
} public void RemoveHandler(T key, Delegate value)
{
ListEntry e = Find(key);
if (e != null) {
e.m_handler = Delegate.Remove(e.m_handler, value);
}
} private sealed class ListEntry
{
internal ListEntry m_next;
internal T m_key;
internal Delegate m_handler; public ListEntry(T key, Delegate handler, ListEntry next)
{
m_next = next;
m_key = key;
m_handler = handler;
}
}
}

有了它,我们就可以改变多个事件的使用方式,例子类似于下面这个。

 public class DispatcherCore
{
readonly EventHandlerList<EventType> Events = new EventHandlerList<EventType>(); public event EventHandler OnReceiveData {
add {
Events.AddHandler(EventType.ReceiveData, value);
}
remove {
Events.RemoveHandler(EventType.ReceiveData, value);
}
} public event EventHandler OnRefreshData
{
add{
Events.AddHandler(EventType.RefreshData, value);
}
remove{
Events.RemoveHandler(EventType.RefreshData, value);
}
} private void RaiseEvent(EventType eventType, EventArgs args)
{
var raiseEvent = Events[eventType] as EventHandler; if (raiseEvent != null)
raiseEvent(this, args);
} // 其它逻辑,在适当的时候调用RaiseEvent private enum EventType
{
None,
ReceiveData,
RefreshData,
Error,
Info,
}
}

用起来更方便,很难出错。希望对大家有用。

类型安全的EventHandlerList的更多相关文章

  1. EventHandlerList z

    写一个类时,有时候会在同一个类上添加很多事件,事件很多的话,是不容易管理的,.NET提供的EventHandlerList可以辅助多个事件的管 理,但不方便的地方是,它不是类型安全的,缺少类型安全,多 ...

  2. 04_Swift2基础之类型安全和类型推测+字面量+类型别名

    1. 类型安全和类型推测 1> 类型安全 Swift 是一个 _类型安全(type safe)_ 的语言.类型安全的语言可以让你清楚地知道代码要处理的值的类型.如果你的代码需要一个`String ...

  3. c++ 类型安全

    类型安全很大程度上可以等价于内存安全,类型安全的代码不会试图访问自己没被授权的内存区域.“类型安全”常被用来形容编程语言,其根据在于该门编程语言是否提供保障类型安全的机制:有的时候也用“类型安全”形容 ...

  4. 类型安全且自动管理内存的返回 std::string 的 sprintf 实现

    在这篇博文里,我提到了一个例子,说的是使用C++实现类型安全的printf.这个例子很惊艳,但是在我写程序的时候,并非那么"迫切"地需要它出现在我的工具箱中,因为它并不比普通的pr ...

  5. Qt信号槽机制的实现(面试的感悟,猜测每一个类保存的一个信号和槽的二维表,实际使用函数指针 元对象 还有类型安全的检查设定等等)

    因为面试时问了我这道题,导致我想去了解信号槽到底是如何实现的,于是贴着顺序看了下源码,大致了解了整个框架.网上关于信号槽的文章也很多,但是大部分都是将如何应用的,这里我就写一下我所理解的如何实现吧, ...

  6. Swift编程语言学习1.3——类型安全和投机型

    Swift 是类型安全(type safe )语言.类型安全的语言可以让你清楚地知道代码被处理值类型.假设你需要一个代码String.你绝对不能进去一个不小心传球Int. 因为 Swift 它是类型安 ...

  7. Matlab与.NET基于类型安全的接口混合编程入门

    原文:[原创]Matlab与.NET基于类型安全的接口混合编程入门 如果这些文章对你有用,有帮助,期待更多开源组件介绍,请不要吝啬手中的鼠标. [原创分享]Matlab.NET混编调用Figure窗体 ...

  8. Swift语言指南(四)--类型安全和类型推断

    原文:Swift语言指南(四)--类型安全和类型推断 Swift是一门类型安全语言,类型安全语言需要代码里值的类型非常明确.如果你的代码中有部分值需要String类型,你就不能错误地传递Int. 鉴于 ...

  9. 自动类型安全的.NET标准REST库refit

    在SCOTT HANSELMAN 博客上看到一个好东西<Exploring refit, an automatic type-safe REST library for .NET Standar ...

随机推荐

  1. 【Sublime】Sublime插件

    alignmentcodecs33convertToUtf8sublimeAstyleFormattersublimeLintersublimeLInter-contrib-clangtagInput ...

  2. redis有序集合类型sort set

    redis的数据类型之-有序集合 sort set和set类型一样,也是string类型元素的集合,也没有重复的元素,不同的是sort set每个元素都会关联一个权,通过权值可以有序的获取集合中的元素 ...

  3. 第一个hibernate程序HelloWorldHibernate

    HelloWorldHibernate步骤: HelloWorld 1,新建java项目hibernate_0100_HelloWorld 2,学习User-library-hibernate,并加入 ...

  4. Determining IP information for eth0...failed

    事故现场 eth0 Link encap:Ethernet HWaddr :0C::B6:D2:5A inet6 addr: fe80::20c:29ff:feb6:d25a/ Scope:Link ...

  5. 【Qt开发】QTime类

    QTime类为用户提供一系列时间的函数,封装的很全面,几乎满足了各种时间的需求. 常用方法介绍 1.QTime addMSecs(int ms) const 当前时间增加毫秒,ms可为负 2.QTim ...

  6. SpringMVC 的工作机制

    在一个工程中如果想要使用 SpringMVC的话,只需要两个步骤 在web.xml中配置一个DispatcherServlet.需要配置一个org.springframework.web.servle ...

  7. java多线程---------java.util.concurrent并发包----------ThreadPoolExecutor

    ThreadPoolExecutor线程池 一.三个构造方法 ThreadPoolExecutor(int corePoolSize,int MaxmumPoolSize,long KeepAlive ...

  8. Linux文件夹打包发送到本地

    tar -cvf script.tar scriptsz script.tar 具体:  sz/rz命令:  一般来说,linux服务器大多是通过ssh来进行远程的登陆和管理的,如何在命令方式下上传和 ...

  9. CSS- 文本超出指定宽度后隐藏并显示为省略号

    一般的文字截断(适用于内联与块): .text-overflow { display:block;/*内联对象需加*/ width:25em; word-break:keep-all;/* 不换行 * ...

  10. 微信小程序自学过程中遇到的问题 转

    view标签下hover必须为true时,设置hover-class才有效,hover-start-time和hover-stay-time的形式如下:   < view class=" ...