1

我正在尝试重构一些看起来像这样的代码(还有其他几种情况)。

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...]
}

我想将代码更改为这样的代码,但我看不到任何将模板化类型(即 EventArgs 事件处理程序)放入 Action 的方法。

var Map = new Dictionary<string, Action<???, string>> {
    { "1", method1},
    { "2", method2}
};

有没有办法做到这一点,或者我可以使用字典并能够编写类似代码的另一种方法:

Map[input](something-with-eventargs, strSomething);
4

2 回答 2

1

我没有找到让编译器推断EventHandler参数类型的方法,但这是我的想法:

假设我们有一个服务(只是为了测试):

public class Service
{
    public event EventHandler<MouseEventArgs> fooEvent1 = delegate { };
    public event EventHandler<KeyEventArgs> fooEvent2 = delegate { };

    public void Fire()
    {
        fooEvent1(null, null);
        fooEvent2(null, null);
    }
}

考虑这个通用类:

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;
        }
    }
}

它将 a 映射string到 a EventHandler<T>。显然,我们将针对不同的T. 为了管理它们,让我们使用以下静态类:

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;
    }
}

现在我们可以按如下方式使用它:

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";
    }
}
于 2012-11-28T00:20:13.930 回答
0

你的 Action 甚至需要输入吗?你不能做这样的事情吗?

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);
};
于 2012-11-28T21:13:34.283 回答