以下の例を考えてみましょう。最初にデリゲート型の変数を定義すると、デリゲートの拡張メソッドを呼び出すことができます。しかし、引数として渡されるデリゲートでその拡張メソッドを呼び出すことはできません。最初はうまくいくのに、2回目はうまくいかない理由がわかりません。私は何を間違っていますか?
public static class Extender
{
public static Func<String, String> Compose(this Func<String, String> outer, Func<String, String> inner)
{
return input => outer(inner(input));
}
}
public class Demo
{
public void WillingToTakeStringToStringDelegate(Func<String, String> map)
{
// blah
}
public void RunMe()
{
Func<String, String> outer = x => "(outer: " + x + ")";
// this works:
var composition = outer.Compose(x => "(inner: " + x + ")");
Trace.Write(composition("!")); // ---> (outer: (inner: !))
// this doesn't work:
this.WillingToTakeStringToStringDelegate(
(x => "(outer: " + x + ")").Compose(y => "(inner: " + y + ")")
);
}
}
アップデート
@philologonのために
ラムダを変数に代入することを気にしない限り、この方法を使用して、上司のように関数の部分的な適用 (カリー化) を作成できます。
public static class CurryingHelper
{
public static Func<X> Apply<A, X>(this Func<A, X> fun, A a)
{
return () => fun(a);
}
public static Func<B, X> Apply<A, B, X>(this Func<A, B, X> fun, A a)
{
return b => fun(a, b);
}
public static Func<B, C, X> Apply<A, B, C, X>(this Func<A, B, C, X> fun, A a)
{
return (b, c) => fun(a, b, c);
}
public static Func<B, C, D, X> Apply<A, B, C, D, X>(this Func<A, B, C, D, X> fun, A a)
{
return (b, c, d) => fun(a, b, c, d);
}
// etc...
}
public class Demo
{
public void RunMe()
{
Func<Int32, Int32, Int32, Int32> func = (a, b, c) => a - b + c;
var funcA1 = func.Apply(1);
Trace.Write(funcA1(2, 3)); // --> 2
Trace.Write(funcA1.Apply(2).Apply(3)()); // --> 2
}
}