4

エクスプレッションについてもう少し学ぶために、黄金の時間をとることにしました。私は非常に簡単な演習、つまり2つの数値を追加しようとしています。検索が難しいことが判明している例外に遭遇しました。

これが私のコードです

Expression<Func<int,int,int>> addExpr = (x, y) => x + y;
var p1 = Expression.Parameter(typeof(int), "p1");
var p2 = Expression.Parameter(typeof(int), "p2");
var lambda = Expression.Lambda<Func<int,int,int>>(addExpr, p1, p2); //<-here
var del = lambda.Compile();
var result = del(2,3); //expect 5

しかし、これはArgumentExceptionをスローしています:タイプ'System.Func`3 [System.Int32、System.Int32、System.Int32]'の式はリターンタイプ'System.Int32'には使用できません

上記の行で。私は何を間違えましたか?

4

3 に答える 3

4

addExpr式パラメータを使用して、呼び出しでラップする必要があります

Expression<Func<int,int,int>> addExpr = (x, y) => x + y;
var p1 = Expression.Parameter(typeof(int), "p1");
var p2 = Expression.Parameter(typeof(int), "p2");
var invokeExpression=Expression.Invoke(addExpr,p1,p2);
var lambda = Expression.Lambda<Func<int,int,int>>(invokeExpression,p1,p2);
var del = lambda.Compile();
var result=del(2,3);

呼び出しは、p1をxに、p2をyに入力する方法です。あるいは、上記のように書くこともできます。

var p1 = Expression.Parameter(typeof(int), "p1");
var p2 = Expression.Parameter(typeof(int), "p2");
var lambda=Expresion.Lambda<Func<int,int,int>>(Expression.Add(p1,p2),p1,p2);
var del = lambda.Compile();
var result=del(2,3);

それ以外の場合は、式の本体をラムダに取り込み、式のパラメーターを渡す必要があります。

var lambda=Expresion.Lambda<Func<int,int,int>>(addExpr.Body,addExpr.Parameters);
于 2012-09-05T12:36:04.933 に答える
2

コードは次のようになります。

var lambda = Expression.Lambda<Func<Expression<Func<int, int, int>>, int, int>(addExpr, p1, p2);

現在のコードでは、intとの受け渡しが必要Expression<Func<int, int, int>>です。

アップデート

実際には、上記はコンパイルされません。次のことを行う必要があります。

var lambda = Expression.Lambda<Func<int, int, int>>(Expression.Add(p1, p2), p1, p2);
于 2012-09-05T12:29:24.107 に答える
1

の本体を分解する必要があります。または、できれば、からではなく、addExpr最初から書き込む必要があります。Expression.Add(p1,p2)addExpr

于 2012-09-05T12:32:59.550 に答える