2010-10-05 44 views
4

在c#中,我们可以通过各种方式创建委托(例如,动作<>,函数<>,委托,lambdas等)。但是,当你调用这些方法,你必须提供委托的参数值要调用:如何在C#中创建完全参数化的方法委托?

delegate int del(int i); 
del myDelegate = x => x * x; 
int j = myDelegate(5); 

有没有在C#的方式来封装具有参数值的方法的委托?基本上延迟了完全参数化方法的调用?所以你不必在调用时提供参数值?

例如这样的无效代码:

delegate int del(int i); 
del myDelegate(5) = x => x * x; 
int j = myDelegate; 

我知道该用例是不是很明显。在我目前正在研究的情况下,我有一个非确定性方法,我希望调用方能够调用而不必包含或知道方法所需的参数。实现这一点的一种方法是通过创建一个封装了参数值和方法委托的类,并让调用者引用和调用它。但我只是好奇,如果有一种替代,更简洁的方式。

回答

12

这就是所谓的currying

例如:

Action curried =() => myFunc(5); 

或者,

Func<int, int, int> multiplier = (x, y) => x * y; 
Func<int, int> doubler = x => multiplier(x, 2); 
int eight = doubler(4); 
1

你总是可以将一个代表包装在另一个代表中。作为SLaks提到的,这就是所谓的currying

Func<int, int> square = i => i * i; 
Func<int> squareFive =() => square(5); 

int j = squareFive(); 
1
Func<int, int> myDelegate = x => x * x; 
Func<int> myDelegate5 =() => myDelegate(5); 
int j = myDelegate5(); 
0

这可以合理地很好做不lambda表达式,具有一定的通用类和辅助功能的帮助。我在一些vb.net/vs2005代码中使用了这种方法。如果目标是产生一个MethodInvoker,它调用一个包含T,U和V三个参数的函数,然后创建一个类ParamInvoker < T,U,V >其中包含字段param1,param2和param3(类型T, U和V)以及Action(类型为Action < T,U,V >)并且具有调用Action(param1,param2,param3)的DoIt(void)方法。泛型类和辅助函数具有重复性,但语法非常好。例如(vb语法,从内存和C#语法猜测):

 
    TheMethodInvoker = MakeParamInvoker(AddressOf MyFunction, 5, "Hello") 
or 
    TheMethodInvoker = MakeParamInvoker(MyFunction, 5, "Hello") 

假设MyFunction接受一个整数和一个字符串。