2009-01-04 17 views
28

Dado un método DoSomething que toma una función (sin parámetros) y la maneja de alguna manera. ¿Hay una mejor manera de crear las "sobrecargas" para funciones con parámetros que el fragmento a continuación?Corrección adecuada en C#

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

Aquí hay un par de publicaciones que pueden ser interesantes si está tratando de curry en C#: http://blogs.msdn.com/wesdyer/archive /2007/01/29/currying-and-partial-function-application.aspx http://diditwith.net/2007/10/23/BuildingFunctionsFromFunctionsPart2FunctionComposition.aspx –

+1

¿Ha revisado esta publicación de blog? [http://mikehadlow.blogspot.com/2008/03/currying-in-c-with-oliver-sturm.html](http://mikehadlow.blogspot.com/2008/03/currying-inc-c- with-oliver-sturm.html) – rodbv

+0

+1 para el enlace de wesdyer: obtendrá una comprensión realmente sólida de algunos conceptos menos entendidos si también lee la publicación de Fibonacci relacionada: http://blogs.msdn.com/b /wesdyer/archive/2007/02/02/anonymous-recursion-in-c.aspx – Jordan

Respuesta

29

EDITAR: Como se señala en los comentarios, esta es una aplicación parcial en lugar de currying. Escribí un blog post on my understanding of the difference, que la gente puede encontrar interesante.

Bueno, no es particularmente diferente - pero me separe la parte currificación de la "HacerAlgo llamando" parte:

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 

continuación:

DoSomething(Apply(foo, 1)); 

De esta manera se puede reutilizar el currying code en otras situaciones, incluidos los casos en los que no desea llamar al delegado recién devuelto inmediatamente. (Es posible que desee curry más más adelante, por ejemplo.)

+1

¿Por qué devuelve Func en lugar de Func >? – Paco

+1

Porque Func es lo que desea que pueda pasar a DoSomething. La idea es que el método Curry tome una función que tome algunos parámetros, así como valores para esos parámetros, y devuelva una función que tome menos parámetros (0 en este caso). –

+0

Pensé que la idea era que un Func se debería convertir a una función con menos parámetros Func >. Puede crear un dosomehing predeterminado con muchos parámetros y variantes cursivas – Paco

Cuestiones relacionadas