有没有办法在C#中重构此事件处理代码

时间:2012-11-28 00:08:23

标签: c# refactoring

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

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

2 个答案:

答案 0 :(得分: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;
        }
    }
}

它将string映射到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";
    }
}

答案 1 :(得分:0)

您的行动甚至需要输入吗?你不能做这样的事吗?

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