2017-05-30 1 views
1

いくつかのパラメータをカリングするメソッドへのデリゲートを動的に作成できますか(また、式のコンパイルやDynamicInvokeを使わずに) DynamicInvokeでいくつかのパラメータをカリングするメソッドへのデリゲートを動的に作成できますか(式のコンパイルやDynamicInvokeを使わずに)

カリー化は、式のラムダで

var methodInfo = typeof(MyTools).GetTypeInfo().GetDeclaredMethod(nameof(MyTools.MyMethod)); 
var delegateType = typeof(Func<,,>).MakeGenericType(typeof(int), typeof(int), typeof(int)); 
var @delegate = methodInfo.CreateDelegate(delegateType); 
var i2 = 1; 
var func = (i1) => { return (int)(@delegate.DynamicInvoke(i1, i2)); }; 

ようになり呼び出すには、それも可能であるコンパイルが、私はそこにそれをスキップ。

私の検索では、i2を受け入れるいくつかの追加パラメータが必要です。curryingを実行し、タイプFunc <のデリゲートを返します。

P.S.ラムダコンパイルの価格は、JIT_MethodAccessCheckのために実行時に発生するオーバーヘッドです。私はJIT_MethodAccessCheckを使わずに削除を作成することができるはずです。

答えて

1

さまざまな引数カウントを持つメソッドの上書きのシリーズを作成することにより、任意の関数をカレーことができます。

public static class Prelude 
{ 
    public static Func<T1, Func<T2, R>> curry<T1, T2, R>(Func<T1, T2, R> f) => 
     (T1 a) => (T2 b) => f(a, b); 

    public static Func<T1, Func<T2, Func<T3, R>>> curry<T1, T2, T3, R>(Func<T1, T2, T3, R> f) => 
     (T1 a) => (T2 b) => (T3 c) => f(a, b, c); 

    public static Func<T1, Func<T2, Func<T3, Func<T4, R>>>> curry<T1, T2, T3, T4, R>(Func<T1, T2, T3, T4, R> f) => 
     (T1 a) => (T2 b) => (T3 c) => (T4 d) => f(a, b, c, d); 

    // ... etc ... 
} 

次の私は、私はあなたのMyTools.MyMethodがどのように見えると思う何のためのプレースホルダ機能を定義します。

using static Prelude; 

public class CurryTest 
{ 
    public void Test() 
    { 
     var f = curry<int, int, int>(MyTools.MyMethod<int, int, int>); 

     var c = f(1)(2); 
    } 
} 

マイfunctional language extensions library

currying

+0

partial applicationが、私は同じデリゲートを構築するためにあなたが必要とするすべてのオーバーライドがありますが、それを動的に構築する:

public static class MyTools { public static C MyMethod<A, B, C>(A a, B b) => default(C); } 

そして、それをテストします。 T1、T2、T3、T4がType [3]配列であり、同じことをする必要があるとします。 –

+0

多分私は質問を誤解しています。なぜそれを動的に作成していますか?これを行うためにリフレクションを使用することは、ほぼ確実に遅くなります。このような関数をカレーする唯一の方法は、ネストされた 'Func'であるため、ラムダを構築する必要があります。 – louthster

関連する問題