As a disclaimer, I am completely new to C#. That been said, I was looking for a lightweight pub/sub library in C# I can use which would be similar to something like this in Javascript that I am used to. However all I could find was for .NET version 4 or higher. I have to use .NET 3.5. So I decided to write my own and I call this an EventBus. The goal is to have other classes to freely subscribe / publish events that are pre-defined in the EventBus. However I found out that the "event" in C# is not first class citizen so I couldn't pass that as a parameter to a function. So I decided to pass enum instead to indicate which event is of interest at the moment. My EventBus works fine as intended but as you can see in my code, I run into the problem of keep writing switch cases in all 3 functions whenever I add a new event. Here is my code.
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
}
Is there a way to achieve all of the subscribe / unsubscribe / publish actions without switch statements like this? I was wondering how C#'s reflection could help in this situation. Maybe once the enum (or a literal string) is passed to indicate an event, it is used to find the event using reflection and perform the action?
You don't need reflection, you can use an EventHandlerList
. However, the EventHandlerList
does not take an enum, but an object
as a key. But you can easily overcome this restriction with an intermediate dictionary:
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);
}
You will probably want to take a look at the IObservable<T>
/ IObserver<T>
interfaces, which are the .NET publish/subscribe interfaces.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.