逐个向委托添加参数然后执行它

时间:2016-10-28 03:21:36

标签: c# exception-handling delegates delayed-execution

昨天我想创建一个ExceptionHandler类,例如我们可以传递给它:

  • 例外
  • 发生这种情况的方法
  • 给予该方法的参数

ExceptionHandler将实现自定义业务逻辑并使用相同的参数自动(或不)重新执行该方法。

The closest solution I found使用delegate这样的

private void button1_Click(object sender, EventArgs e)
{
    InvokeMyMethod(Test, "string", 1);
    InvokeMyMethod(TestN, "other string", 3, Color.Red);
}

public delegate void MyMethodDelegate(params object[] args);

public void InvokeMyMethod(MyMethodDelegate method, params object[] args)
{
    method.DynamicInvoke(args);
}

public void Test(params object[] args)
{
    if (args.Length < 2) return;
    MessageBox.Show(string.Format("{0}{1}", args[0], args[1]));
}

public void TestN(params object[] args)
{
    // or, whatewer
    if (args.Length < 3) return;
    MessageBox.Show(string.Format("{0}{1}{2}", args[0], args[1], args[2]));
}

然而,由于方法的原因,这种解决方案仍然不完善。签名。我不希望我的所有方法都接收到唯一的参数params object[] args,而且这通常不可能直接用于所有与UI相关的事件(Winform,ASP.NET,WPF或其他)。

所以我想知道是否有办法将一个一个参数传递给一个委托,然后只有在我们准备好之后才执行该函数?

例如,这里有一个虚构的代码,其中包含不存在的方法AddArgumentExecute

public void InvokeMyMethod(MyMethodDelegate method, params object[] args)
{
    foreach(var arg in args)
    {
        method.AddArgument(arg);
    }
    method.Execute();
}

通过这种方式,我们所有的函数都可以保留原始签名并接收多个参数而不是数组。

1 个答案:

答案 0 :(得分:1)

您的原始代码并不遥远。你可以摆脱要求所有被调用的方法具有相同的签名,只要你使InvokeMyMethod只采用抽象的Delegate类,并在调用函数时显式指定委托类型(它不会推断类型)。我们可以利用C#中存在泛型委托类型的事实,因此我们不需要声明我们想要使用的每个可能的方法签名集。

如果您想调用带有返回值的函数,则需要使用Func<>代替Action<>

private void button1_Click(object sender, EventArgs e)
{
    InvokeMyMethod((Action<string,int>) Test, "string", 1);
    InvokeMyMethod((Action<string,int,Color>) TestN, "other string", 3, Color.Red);
}

public void InvokeMyMethod(Delegate method, params object[] args)
{
    method.DynamicInvoke(args);
}

public void Test(string s, int i)
{
    MessageBox.Show(string.Format("{0}{1}", s, i));
}

public void TestN(string s, int i, Color c)
{
    // or, whatewer
    MessageBox.Show(string.Format("{0}{1}{2}", s, i , c);
}