多くのパラメーターを持つ式ツリーの計算
-
07-07-2019 - |
質問
.Net 3.5のExpressionツリーとLamdba Expressionオブジェクトを使用して、ユーザーが入力したブール式を動的に計算できるようにします。
これまで、ユーザーは、BinarayExpressions
で表されるANDおよびOR値であるParameterExpressions
で構成される式ツリーを作成できます。次に、そのツリーに基づいてLambdaExpression
を作成し、式をコンパイルしてデリゲートを呼び出して呼び出すことができるようにすることを計画していました。私が抱えている問題は、ユーザーが必要とする入力パラメーターの数がわからないため、式をデリゲートにコンパイルするときに、メソッドのシグネチャが実行時まで何であるかがわからないことです。
これまでのところ、2つの可能な解決策を考え出しました。
- 多数のデリゲートを作成する
Func<bool, bool, bool...>
のように ユーザーが必要とする可能性があると思われる数のパラメーターを使用します。これは最もエレガントなソリューションのようには感じませんが、誰かが私が用意したよりももう1つのパラメーターを使用するまで、うまくいくと思います。 - 値の配列を渡し、配列インデクサーを使用して何らかの方法でそれらをパラメーターに割り当てます。私はこれについて考えましたが、それがどのように機能するかを理解することはできません。
NB:ボクシングなどが必要ないため、高速である必要があります。
解決
配列アプローチを使用して、これまで正確に実行しました(言語学。トリックはExpression.ArrayIndex
:
var arr = Expression.Parameter(typeof(int[]), "arr");
var body = Expression.ArrayIndex(arr, Expression.Constant(1));
var expr = Expression.Lambda<Func<int[], int>>(body, arr);
var func = expr.Compile();
int[] vals = { 7, 8, 9 };
int i = func(vals);
配列アプローチの利点は、引数の数に関係なく、厳密に型指定されたデリゲート型(Func<int[],int>
または類似のものを保持できることです。また、型付きInvoke
はDynamicInvoke
よりもはるかに高速です。
値がすべて同じ型ではない場合-それも実行可能です。お知らせください。例を追加します。
所属していません StackOverflow