我們寫一個類時,有時候會在同一個類上添加很多事件,事件很多的話,是不 容易管理的,.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,
}
}
用起來更方便,很難出錯。希望對大家有用。
查看本欄目