Reputation: 69
I'm trying to refactor some code that looks like this (there are several other cases).
switch (input) {
case "1":
_service.getWCFStuff1Completed += new EventHandler<getWCFStuff1CompletedEventArgs>(method1);
_service.getWCFStuff1Async(strSomething);
case "2":
_service.getWCFStuff2Completed += new EventHandler<getWCFStuff2CompletedEventArgs>(method2);
_service.getWCFStuff2Async(strSomething);
[etc...]
}
I'd like to change the code to something like this but I don't see any way to get a templated type (i.e. the EventArgs event handler) into an Action.
var Map = new Dictionary<string, Action<???, string>> {
{ "1", method1},
{ "2", method2}
};
Is there any way to do this, or another approach in which I can use a Dictionary and be able to write code something like:
Map[input](something-with-eventargs, strSomething);
Upvotes: 1
Views: 402
Reputation: 2284
Does your Action even need to be typed? Can't you do something like this?
var map = new Dictionary<string, Action>();
map["1"] = () =>
{
_service.getWCFStuff1Completed +=
new EventHandler<getWCFStuff1CompletedEventArgs>(method1);
_service.getWCFStuff1Async(strSomething);
};
map["2"] = () =>
{
_service.getWCFStuff2Completed +=
new EventHandler<getWCFStuff2CompletedEventArgs>(method2);
_service.getWCFStuff2Async(strSomething);
};
Upvotes: 0
Reputation: 18534
I failed to find the way to make compiler infer EventHandler
parameter type, but here are my thoughts:
Suppose we have a service (just to test):
public class Service
{
public event EventHandler<MouseEventArgs> fooEvent1 = delegate { };
public event EventHandler<KeyEventArgs> fooEvent2 = delegate { };
public void Fire()
{
fooEvent1(null, null);
fooEvent2(null, null);
}
}
Consider this generic class:
class Map<T> where T : EventArgs
{
Dictionary<string, EventHandler<T>> map;
public Map()
{
map = new Dictionary<string, EventHandler<T>>();
}
public EventHandler<T> this[string key]
{
get
{
return map[key];
}
set
{
map[key] = value;
}
}
}
It maps a string
to an EventHandler<T>
. Obviously we'll have different classes for different T
. To manage them let's take the following static class:
static class Map
{
static Dictionary<Type, object> maps = new Dictionary<Type, object>();
public static Map<U> Get<U>() where U : EventArgs
{
Type t = typeof(U);
if (!maps.ContainsKey(t))
maps[t] = new Map<U>();
Map<U> map = (Map<U>)maps[t];
return map;
}
}
Now we can use it as follows:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Map.Get<MouseEventArgs>()["1"] = Form1_fooEvent1;
Map.Get<KeyEventArgs>()["2"] = Form1_fooEvent2;
Service s = new Service();
s.fooEvent1 += Map.Get<MouseEventArgs>()["1"];
s.fooEvent2 += Map.Get<KeyEventArgs>()["2"];
s.Fire();
}
void Form1_fooEvent2(object sender, KeyEventArgs e)
{
textBox2.Text = "Form1_fooEvent2";
}
void Form1_fooEvent1(object sender, MouseEventArgs e)
{
textBox1.Text = "Form1_fooEvent1";
}
}
Upvotes: 1