37

DoSomething(パラメーターなしの)関数を取り、それを何らかの方法で処理するメソッドが与えられます。以下のスニペットよりも、パラメーターを使用して関数の「オーバーロード」を作成するためのより良い方法はありますか?

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);
}
4

3 に答える 3

39

編集:コメントに記載されているように、これはカリー化ではなく部分適用です。私はその違いについての私の理解についてブログに投稿しました。人々はそれを面白いと思うかもしれません。

さて、それは特に違いはありませんが、カリー化の部分を「DoSomethingの呼び出し」の部分から分離します。

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

それで:

DoSomething(Apply(foo, 1));

そうすれば、新しく返されたデリゲートをすぐに呼び出したくない場合など、他の状況でカリー化コードを再利用できます。(たとえば、後でもっとカレーしたいと思うかもしれません。)

于 2009-01-04T20:02:52.307 に答える
0

dynamicこれは、 (jsのCurryのような)を使用して関数の無制限の呼び出しを書くことを可能にする方法です:

dynamic Sum(int a)
{
    Console.WriteLine(a);
    return new Func<int, dynamic>(b => Sum(a + b));
}

このように呼び出すとSum(2)(3)(4)(10)、出力は次のようになります。

2
5
9
19
于 2021-04-17T12:31:15.213 に答える