I was looking through some old code today and found an event handler that looked like this:
public void HandleEvent(EventClassA eventObj)
{
if(eventObj is EventSubClassA)
{
HandleEventSubClassA(eventObj as EventSubClassA);
}
else if(eventObj is EventSubClassB)
{
HandleEventSubClassB(eventObj as EventSubClassB);
}
else if(eventObj.GetType() == typeof(EventSubClassC))
{
HandleEventSubClassC(eventObj as EventSubClassC);
}
else if(eventObj is EventSubClassD)
{
HandleEventSubClassD(eventObj as EventSubClassD);
}
}
I thought this was kind of ugly. So I refactored it like this:
delegate void EventHandler(dynamic eventObj);
private static readonly Dictionary<Type, EventHandler> EVENT_MAP = new Dictionary<Type, EventHandler>()
{
{ typeof(EventSubClassA), HandleEventSubClassA },
{ typeof(EventSubClassB), HandleEventSubClassB },
{ typeof(EventSubClassC), HandleEventSubClassC },
{ typeof(EventSubClassD), HandleEventSubClassD }
};
public void HandleEvent(EventClassA eventObj)
{
EVENT_MAP[eventObj.GetType()](eventObj);
}
private void HandleEventSubClassA(dynamic evt)
{
var eventObj = evt as EventSubClassA;
}
I had a coworker review the code and there were concerns about the way this solution worked compared to the previous solution. I have a hard time believing that the previous solution is the best solution for this case, so I’ve turned to StackOverflow.
Is there a better way to build this type of class?
Is there a pattern I’m not aware of that is designed for this?
You can use generics to make your existing solution slightly safer:
Alternatively, if you can modify the classes in your event hierarchy you could implement the visitor pattern: