类型安全的EventHandlerList
我们写一个类时,有时候会在同一个类上添加很多事件,事件很多的话,是不容易管理的,.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的更多相关文章
- EventHandlerList z
写一个类时,有时候会在同一个类上添加很多事件,事件很多的话,是不容易管理的,.NET提供的EventHandlerList可以辅助多个事件的管 理,但不方便的地方是,它不是类型安全的,缺少类型安全,多 ...
- 04_Swift2基础之类型安全和类型推测+字面量+类型别名
1. 类型安全和类型推测 1> 类型安全 Swift 是一个 _类型安全(type safe)_ 的语言.类型安全的语言可以让你清楚地知道代码要处理的值的类型.如果你的代码需要一个`String ...
- c++ 类型安全
类型安全很大程度上可以等价于内存安全,类型安全的代码不会试图访问自己没被授权的内存区域.“类型安全”常被用来形容编程语言,其根据在于该门编程语言是否提供保障类型安全的机制:有的时候也用“类型安全”形容 ...
- 类型安全且自动管理内存的返回 std::string 的 sprintf 实现
在这篇博文里,我提到了一个例子,说的是使用C++实现类型安全的printf.这个例子很惊艳,但是在我写程序的时候,并非那么"迫切"地需要它出现在我的工具箱中,因为它并不比普通的pr ...
- Qt信号槽机制的实现(面试的感悟,猜测每一个类保存的一个信号和槽的二维表,实际使用函数指针 元对象 还有类型安全的检查设定等等)
因为面试时问了我这道题,导致我想去了解信号槽到底是如何实现的,于是贴着顺序看了下源码,大致了解了整个框架.网上关于信号槽的文章也很多,但是大部分都是将如何应用的,这里我就写一下我所理解的如何实现吧, ...
- Swift编程语言学习1.3——类型安全和投机型
Swift 是类型安全(type safe )语言.类型安全的语言可以让你清楚地知道代码被处理值类型.假设你需要一个代码String.你绝对不能进去一个不小心传球Int. 因为 Swift 它是类型安 ...
- Matlab与.NET基于类型安全的接口混合编程入门
原文:[原创]Matlab与.NET基于类型安全的接口混合编程入门 如果这些文章对你有用,有帮助,期待更多开源组件介绍,请不要吝啬手中的鼠标. [原创分享]Matlab.NET混编调用Figure窗体 ...
- Swift语言指南(四)--类型安全和类型推断
原文:Swift语言指南(四)--类型安全和类型推断 Swift是一门类型安全语言,类型安全语言需要代码里值的类型非常明确.如果你的代码中有部分值需要String类型,你就不能错误地传递Int. 鉴于 ...
- 自动类型安全的.NET标准REST库refit
在SCOTT HANSELMAN 博客上看到一个好东西<Exploring refit, an automatic type-safe REST library for .NET Standar ...
随机推荐
- 微信 oauth 登录 ,回调两次,一个坑,记录一下。
在做微信某个功能的时候,大致需求是:静默授权,得到openId ,然后拿着openId调用接口,判断是否关注.如果是关注的,则发放礼券.每个我网站的会员只会发放一次礼券.如果第二次则会提示已领取过礼券 ...
- WP调用api
private string GetText() { string resultString = string.Empty; HttpWebRequest request = HttpWebReque ...
- java 并发编程——Thread 源码重新学习
Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...
- 完美解决linux系统sublime不能输入中文
1.下载git项目:sublime-text-imfix,主要是要用到里面的两个文件 subl和libsublime-imfix.so git项目路径:https://github.com/lyf ...
- C# 数组基础
一.数组的基础知识 1.数组有什么用? 如果需要同一个类型的多个对象,就可以使用数组.数组是一种数组结构,它可以包含同一个类型的多个元素. 2.数组的初始化方式 第一种:先声明后赋值 ]; array ...
- TortoiseGit学习系列之Windows上本地代码如何通过TortoiserGit提交到GitHub详解(图文)
不多说,直接上干货! 前面博客 TortoiseGit学习系列之Windows上TortoiseGit的安装详解(图文) 上面博文给大家讲解了一下如何本地安装TortoiseGit. 这篇为大家讲一下 ...
- manjaro 添加tash 快捷方式
-In your home directory open /.local/share/applications/-Right click in this folder and create a emp ...
- linux mint19 解决docker必须使用sudo问题
1 安装完docker 使用时,提示权限不够 ~$ docker info Got permission denied while trying to connect to the Docker da ...
- Cygwin、Msys、MinGW、Msys2的区别与联系(转)
网上有很多文章讲它们之间的区别与联系,初学者看的一头雾水,在知乎上看到这篇文章讲的很清楚,容易理解. 在讲区别联系之前,我们先看一下这几个东东的前世今生. Cygwin,原 Cygnus 出品(已 ...
- Struts2 ongl内存结构
valuestack是OgnlValueStack的实现,而OgnlValueStack是基于ValueStack的实现 valuestack的内存结构为: 里面主要的为:context和root r ...