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

Add arguments one by one to a delegate then execute it

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

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

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

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

如果您想调用具有 return 值的函数,您需要使用 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);
}