编辑:重写,因为我对原始问题的解释很差。
我使用字典允许我根据枚举(EventType)处理事件/处理程序:
Dictionary<EventType, EventHandler<EventArgs>> eventLookup;
为了填充这个字典,我通过一个包含大量事件的类来反映,并为每个事件分配一个新的空EventHandler。然后我将EventType值与每个EventHandler相关联:
public void EngineEvents::Initialize()
{
foreach (EventInfo eventInfo in this.GetType().GetEvents())
{
eventInfo.GetAddMethod(true).Invoke(this, new[] { new EventHandler<EventArgs>(this.UselessHandler) });
}
this.eventLookup = new Dictionary<EventType, EventHandler<EventArgs>>
{
{ EventType.Initialize, this.OnInitialize },
};
}
private void UselessHandler(object sender, EventArgs args) { }
public event EventHandler<EventArgs> OnInitialize;
其他代码可以订阅OnInitialize并应该接收该事件。
engineEvents.OnInitialize += this.OnInitialize;
当一个事件被触发时,我将索引到字典中,并调用多播委托:
public void EngineEvents::FireEvent(EventType eventType)
{
if (this.eventLookup.ContainsKey(eventType))
{
this.eventLookup[eventType](this, new EventArgs());
}
}
这适用于EngineEvents内部完成的任何事情,包含事件和查找字典的类。
当我订阅EngineEvents&#39;来自:
的活动public class CallingClass
{
public CallingClass(EngineEvents engine)
{
engine.OnInitialize += this.OnInitialize;
}
private void OnInitialize(object sender, EventArgs e)
{
Console.WriteLine("calling class's method called");
}
}
永远不会调用此OnInitialize,但EngineEvents中的UselessHandler是。
其他代码如何触发此事件:
engineEvents.FireEvent(EventType.Initialize);
总结一下: 只有EngineEvents&#39; EventHandler保持相关性,并且不会调用事件的外部订阅者。
完整示例,适用于控制台应用程序。 CallingClass的OnInitialize和EngineEvents的UselessHandler上的断点显示一个被调用而不是另一个。
namespace ConsoleApplication2
{
using System;
using System.Collections.Generic;
using System.Reflection;
public class Program
{
static void Main(string[] args)
{
EngineEvents engine = new EngineEvents();
engine.Initialize();
CallingClass calling = new CallingClass(engine);
engine.FireEvent(EventType.Initialize);
}
}
public class EngineEvents
{
private Dictionary<EventType, EventHandler<EventArgs>> eventLookup;
public void Initialize()
{
foreach (EventInfo eventInfo in this.GetType().GetEvents())
{
eventInfo.GetAddMethod(true).Invoke(this, new[] { new EventHandler<EventArgs>(this.UselessHandler) });
}
this.eventLookup = new Dictionary<EventType, EventHandler<EventArgs>>
{
{ EventType.Initialize, this.OnInitialize },
};
}
private void UselessHandler(object sender, EventArgs args) { }
public event EventHandler<EventArgs> OnInitialize;
public void FireEvent(EventType eventType)
{
if (this.eventLookup.ContainsKey(eventType))
{
this.eventLookup[eventType](this, new EventArgs());
}
}
}
public enum EventType
{
Initialize,
}
public class CallingClass
{
public CallingClass(EngineEvents engine)
{
engine.OnInitialize += this.OnInitialize;
}
private void OnInitialize(object sender, EventArgs e)
{
Console.WriteLine("calling class's method called");
}
}
}
答案 0 :(得分:1)
首先,你不能将事件存储在一个词典中。或者其他任何东西。 event
是(一种)属性,不能通过引用存储。您的词典存储了这些属性的内容,代表。
会发生什么:
{ EventType.Initialize, this.OnInitialize },
+=
问题在于,在步骤2)您认为您正在捕获事件。但是您只是在那一刻读取事件并存储委托值(仅包含无用处理程序)
在步骤3)中,您订阅实际事件,字典内的任何内容都不会更改
在步骤4)中,仅调用字典中的委托,而不是事件中更新的委托。