[英]How to register events using reflection in C#
作为免责声明,我是C#的新手。 这已经说了,我一直在寻找在C#中轻量级的pub / sub库我可以用这将是类似像这样在Javascript中,我习惯了。 但是,我所能找到的只是.NET 4或更高版本。 我必须使用.NET 3.5。 因此,我决定编写自己的文件,并将其称为EventBus。 目标是让其他类自由订阅/发布EventBus中预定义的事件。 但是我发现C#中的“事件”不是一等公民,因此我无法将其作为参数传递给函数。 因此,我决定通过枚举来表示当前关注的事件。 我的EventBus可以按预期工作,但是正如您在我的代码中看到的那样,每当添加新事件时,我都会遇到在所有3个函数中始终编写开关用例的问题。 这是我的代码。
public class EventBus {
public delegate void EventListener(object source, EventArgs args);
private static event EventListener MapLocationMarkerClicked;
public static void Subscribe(Event eventToSub, EventListener listener)
{
switch(eventToSub)
{
case Event.MapLocationMarkerClicked:
MapLocationMarkerClicked += listener;
break;
}
}
public static void Unsubscribe(Event eventToUnsub, EventListener listener)
{
switch (eventToUnsub)
{
case Event.MapLocationMarkerClicked:
MapLocationMarkerClicked -= listener;
break;
}
}
public static void Publish(Event eventToPub, object source, EventArgs args)
{
switch (eventToPub)
{
case Event.MapLocationMarkerClicked:
MapLocationMarkerClicked(source, args);
break;
}
}
}
public enum Event
{
MapLocationMarkerClicked
}
有没有一种方法可以实现所有的订阅/取消订阅/发布操作,而无需使用类似switch的语句? 我想知道C#的反思如何在这种情况下有所帮助。 也许一旦枚举(或文字字符串)被传递以指示事件,它就可以通过反射来查找事件并执行操作?
您不需要反射,可以使用EventHandlerList
。 但是, EventHandlerList
并不采用枚举,而是采用object
作为键。 但是您可以使用中间字典轻松克服此限制:
static Dictionary<Event, object> eventMap = new Dictionary<Event, object>() { { Event.MapLocationMarkerClicked, new object() } };
static EventHandlerList events = new EventHandlerList();
public static void Subscribe(Event eventToSub, EventListener listener)
{
events.AddHandler(eventMap[eventToSub], listener);
}
public static void Unsubscribe(Event eventToUnsub, EventListener listener)
{
events.RemoveHandler(eventMap[eventToSub], listener);
}
public static void Publish(Event eventToPub, object source, EventArgs args)
{
EventListener listener = (EventListener)events[eventMap[eventToSub]];
listener?.Invoke(source, args);
}
您可能需要看一下IObservable<T>
/ IObserver<T>
接口,它们是.NET发布/订阅接口。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.