C#中的Action和Func参数重载

8

我需要一个方法,接受一个Action(或Func),但是这个Action有多个不同类型的参数。最简单和紧凑的实现这些重载的方法是什么:

public void Execute<T>(Action<T> action, T param) {
    // TODO: Implement something like:
    // Execute(action, param, null);
}

public void Execute<T1,T2>(Action<T1,T2> action, T1 param1, T2 param2) {
    // TODO: Implement something like:
    // Execute(action, param1, param2, null);
}

public void Execute<T1,T2,T3>(Action<T1,T2,T3> action, T1 param1, T2 param2, T3 param3) {
    DoStuff();
    action(param1, param2, param3)
    DoMoreStuff();
}

// OR any other type of higher order function-solution
public void Execute(Action action, params object[] parameters) { ... } // ???

这些方法的内容完全相同,除了执行的操作和其参数。

如果可能的话,请不要使用任何C# 4.0特定的功能来解决此问题。

2个回答

8

这些方法的内容完全相同,除了执行操作及其参数。

这需要使用高阶函数,但是由于您已经参数化了所有正在发生变化的部分(执行操作及其参数),因此您已经完成了。很抱歉,看起来您必须手动实现这些重载。

仅使用空值进行链接不起作用,因为传递的委托不匹配。您可以包装传递的操作/函数在lambda中以去掉附加的参数

public void Execute(Action<T> action, T param) {
     Execute( (a, _) => action(a) , param, null);
}

public void Execute(Action<T1, T2> action, T1 param1, T2 param2) {
    Execute( (a, b, _) => action(a, b) , param1, param2,  null);
}

public void Execute(Action<T1, T2, T3> action, T1 param1, T2 param2, T3 param3) {
    DoStuff();
    action(param1, param2, param3)
    DoMoreStuff();
}

请随意提供高阶函数解决方案。 - Seb Nilsson
@Seb:关于高阶函数:你已经通过参数化你的操作实现了这一点。 - Johannes Rudolph

5

考虑到 Johannes 提出的你也可以使用高阶函数的方法,实际上这是最佳方式,因为它最符合类型规范(委托将自动匹配正确数量和类型的参数),并且不需要任何烦人的 DynamicInvoke 调用。

然而,你最后的方法定义存在问题。由于 Action 本质上不接受任何参数,因此它不会与 params object[] 参数兼容。如果你想要一个接受可变数量参数的最终重载,我建议你仍然使用 DynamicInvoke,只针对这个方法调用:

public void Execute(Delegate action, params object[] parameters)
{
    DoStuff();
    action.DynamicInvoke(parameters);
    DoMoreStuff();
}

但是针对 Johannes 所说的内容,我认为他基本上是在表达这样一种意思:
public Action<T1, T2, T3> CreateAction<T1, T2, T3>(Action action)
{
    return (T1 x, T2 y, T3 z) => action();
}

public Action<T1, T2, T3> CreateAction<T1, T2, T3>(Action<T1> action, T1 arg)
{
    return (T1 x, T2 y, T3 z) => action(arg);
}

等等 —— 换句话说,就是你已经做过的事情,但在一个更一般的背景下,以便代码可以在其他地方重复使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接