Reputation: 959
In c# we can create delegates via a variety of means (e.g. Action<>, Func<>, delegate, lambdas, etc). But when you invoke those methods, you have to provide the parameter values for the delegate you are invoking:
delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5);
Is there a way in c# to encapsulate a method delegate WITH parameter values? Essentially delay invocation of a fully parametrized method? So you don't have to supply parameter values at invocation time?
For example something like this invalid code:
delegate int del(int i);
del myDelegate(5) = x => x * x;
int j = myDelegate;
I'm aware the use case isn't immediately obvious. In the case I'm currently looking at, I have a non-deterministic method that I would like the caller to be able to invoke without having to contain or be aware of the parameters the method needs. One way to achieve this would be via creating a class that encapsulates both the parameter values and the method delegate and have that referenced and invoked by the caller. But I'm just curious if there is an alternate, more succinct way.
Upvotes: 4
Views: 1827
Reputation: 81115
This can be done reasonably nicely without lambdas, with the aid of some generic classes and helper functions. I used such an approach in some vb.net/vs2005 code. If the goal is to yield a MethodInvoker which calls a function with three arguments of types T, U, and V, then create a class ParamInvoker<T,U,V> which holds fields param1, param2, and param3 (as types T, U, and V), and Action (of type Action<T,U,V>) and has a method DoIt(void) which calls Action(param1, param2, param3). The generic classes and helper functions get repetitive, but the syntax is pretty nice. For example (vb syntax, from memory, and C# syntax, guessing):
TheMethodInvoker = MakeParamInvoker(AddressOf MyFunction, 5, "Hello") or TheMethodInvoker = MakeParamInvoker(MyFunction, 5, "Hello")
assuming MyFunction takes an Integer and a String.
Upvotes: 0
Reputation: 245399
You could always wrap one delegate in another. As SLaks mentioned, this is called currying:
Func<int, int> square = i => i * i;
Func<int> squareFive = () => square(5);
int j = squareFive();
Upvotes: 1
Reputation: 269298
Func<int, int> myDelegate = x => x * x;
Func<int> myDelegate5 = () => myDelegate(5);
int j = myDelegate5();
Upvotes: 1