Given a method DoSomething
that takes a (parameterless) function and handles it in some way. Is there a better way to create the "overloads" for functions with parameters than the snippet below?
public static TResult DoSomething<TResult>(Func<TResult> func) { //call func() and do something else } public static TResult DoSomething<T0, TResult>( Func<T0, TResult> func, T0 arg0) { return DoSomething(() => func(arg0)); } public static TResult DoSomething<T0, T1, TResult>( Func<T0, T1, TResult> func, T0 arg0, T1 arg1) { return DoSomething(arg => func(arg, arg1), arg0); } public static TResult DoSomething<T0, T1, T2, TResult>( Func<T0, T1, T2, TResult> func, T0 arg0, T1 arg1, T2 arg2) { return DoSomething(arg => func(arg, arg1, arg2), arg0); }
Currying is helpful when you have to frequently call a function with a fixed argument. Considering, for example, the following function: If we want to define the function error , warn , and info , for every type, we have two options. Currying provides a shorter, concise, and more readable solution.
to praise someone, especially someone in authority, in a way that is not sincere, in order to get some advantage for yourself: He's always trying to curry favour with the boss.
Currying. Currying is an idea, which is important in contemporary functional programming languages, such as Haskell. In Scheme, however, the idea is less attractive, due to the parenthesized notation of function calls.
The main benefit of currying is when you need to use the same call with some of the same parameters a lot i.e it helps to avoid passing the same variable again and again. In these situations, currying becomes a good technique to use. Currying will make your code easier to refactor.
EDIT: As noted in comments, this is partial application rather than currying. I wrote a blog post on my understanding of the difference, which folks may find interesting.
Well, it's not particularly different - but I'd separate out the currying part from the "calling DoSomething" part:
public static Func<TResult> Apply<TResult, TArg> (Func<TArg, TResult> func, TArg arg) { return () => func(arg); } public static Func<TResult> Apply<TResult, TArg1, TArg2> (Func<TArg1, TArg2, TResult> func, TArg1 arg1, TArg2 arg2) { return () => func(arg1, arg2); } // etc
Then:
DoSomething(Apply(foo, 1));
That way you can reuse the currying code in other situations - including cases where you don't want to call the newly-returned delegate immediately. (You might want to curry it more later on, for example.)
The @Jon Skeet answer is right, but write by hand all possibles overload is something insane, so you can use a lib like Curryfy that do this job for you. Curryfy lib particularly exposes Curry, UnCurry and ApplyPartial extension methods, with a lot of overloads.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With