Seb*_*son 7 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) { ... } // ???
Run Code Online (Sandbox Code Playgroud)
除了执行操作及其参数之外,方法的内容完全相同.
如果可能,请不要使用任何特定于C#4.0的功能来解决此问题.
除了执行操作及其参数之外,方法的内容完全相同.
这对使用更高阶函数感到尖叫,但由于你已经参数化了所有正在改变的位(执行动作及其参数),你已经存在了.抱歉,看起来你必须手动实现这些重载.
只是链接使用空值将无法工作,因为传递的委托不匹配.你可以做的是将传递的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();
}
Run Code Online (Sandbox Code Playgroud)
这实际上是最好的方法(记住Johannes的观点,你也可以使用更高阶的函数),因为它是最类型友好的(委托将自动匹配正确的参数数量和类型)并且不需要任何麻烦的DynamicInvoke电话.
但是,您的上一个方法定义存在问题.从Action本质上讲,它不接受任何参数,所以它不会对params object[]参数有好处.如果你想要一个接受可变数量参数的最终重载,我会继续使用DynamicInvoke,只是为了这个方法调用:
public void Execute(Delegate action, params object[] parameters)
{
DoStuff();
action.DynamicInvoke(parameters);
DoMoreStuff();
}
Run Code Online (Sandbox Code Playgroud)
但是为了扩展约翰内斯所说的话,我认为他基本上是这样的:
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);
}
Run Code Online (Sandbox Code Playgroud)
等等 - 换句话说,你已经完成了什么,但在一般情况下,以便代码可以在其他地方重复使用.