2009-01-04 9 views
28

Eine Methode DoSomething gegeben, die eine (parameterlose) Funktion übernimmt und in irgendeiner Weise verarbeitet. Gibt es eine bessere Möglichkeit, die "Überladungen" für Funktionen mit Parametern als das unten stehende zu erstellen?Korrektes Currieren in 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

Hier sind ein paar Beiträge, die interessant sein könnten, wenn Sie versuchen, in C# curry: http://blogs.msdn.com/wesdyer/archive /2007/01/29/currying-and-partial-function-application.aspx http://diditwith.net/2007/10/23/BuildingFunctionsFromFunctionsPart2FunctionComposition.aspx –

+1

Haben Sie diesen Blogpost überprüft? [http://mikehadlow.blogspot.com/2008/03/currying-in-c-with-oliver-sturm.html](http://mikehadlow.blogspot.com/2008/03/currying-in-c with-oliver-sturm.html) – rodbv

+0

+1 für den Web-Link - Sie werden ein wirklich solides Verständnis einiger weniger verstandener Konzepte bekommen, wenn Sie auch den zugehörigen Fibonacci-Beitrag lesen: http://blogs.msdn.com/b /wesdyer/archive/2007/02/02/anonymous-recursion-in-c.aspx – Jordan

Antwort

29

BEARBEITEN: Wie in den Kommentaren erwähnt, ist dies eine teilweise Anwendung und nicht currying. Ich schrieb eine blog post on my understanding of the difference, die Leute interessant finden können.

Nun, es ist nicht besonders anders - aber ich würde das Striegeln Teil aus dem „Aufruf DoSomething“ Teil trennen:

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 

Dann:

DoSomething(Apply(foo, 1)); 

diese Weise können Sie die wiederverwenden können currying code in anderen Situationen - einschließlich Fällen, in denen Sie den neu zurückgegebenen Delegierten nicht sofort aufrufen möchten. (Vielleicht möchten Sie es später zum Beispiel curry.)

+1

Warum gibt man Func statt Func > zurück? – Paco

+1

Da Func ist, was Sie in DoSomething übergeben möchten. Die Idee ist, dass die Curry-Methode eine Funktion annehmen sollte, die einige Parameter sowie Werte für diese Parameter annimmt und eine Funktion zurückgibt, die weniger Parameter (in diesem Fall 0) benötigt. –

+0

Ich dachte, die Idee war, dass ein Func in eine Funktion mit weniger Parametern umgewandelt werden sollte Func >. Sie können ein Standard-Dosomething mit vielen Parametern und Curry-Varianten erstellen – Paco

Verwandte Themen