C#Action和Func参数重载

时间:2010-08-18 07:49:48

标签: c# parameters action overloading func

我需要一个采用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 个答案:

答案 0 :(得分:8)

  

方法的内容完全正确   同样的,除了执行   行动及其参数。

对使用higher order function感到尖叫,但由于你已经参数化了所有正在改变的位(执行动作及其参数),你已经存在了。抱歉,看起来你必须手动实现这些重载。

由于传递的委托不匹配,因此只使用空值链接将无效。你可以做的是将传递的action / func包装在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();
}

答案 1 :(得分:5)

这实际上是最好的方法(记住Johannes的观点,你也可以使用更高阶的函数),因为它是最类型友好的(委托将自动匹配正确的参数数量和类型)并且不需要任何麻烦的DynamicInvoke电话。

然而,您的上一个方法定义存在问题。 Action本质上不接受任何参数,因此它不会与params object[]参数一起使用。如果你想要一个接受可变数量参数的最终重载,那么毕竟我会选择DynamicInvoke,只是为了这个方法调用:

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

但是为了扩展约翰内斯所说的话,我认为他基本上就是这样:

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

依此类推 - 换句话说,就是你已经完成的事情,但是在一般情况下,代码可以在其他地方重复使用。