2017-07-17 82 views
0

我想從其他表達式構建表達式,使用另一個表達式的結果作爲參數,但我想避免編譯它們。鑑於我有下面的代碼工作代碼我怎樣才能刪除.Compile().Invoke(位,以保持它作爲表達一直到?我可以看到它是Expression.Lambda()和Expression.Invoke()的一個可能組合,但確切的語法是什麼?以編程方式編譯表達式而不編譯它們

Expression<Func<IActivator, TResult>> expressionA = ....;  
Expression<Func<T, TResult, TOut>> expressionB = ....; 

Expression<Func<IActivator,TOut>> invoke_B_With_A = (activator) => 
    expressionB.Compile().Invoke(
     activator.Create<T>(), 
     expressionA.Compile().Invoke(activator) 
    ); 

回答

0

這種方式似乎工作,但你可以把它簡化?

var activatorParam = Expression.Parameter(typeof(IActivator), "activator"); 
Expression<Func<IActivator, T>> builder = (activator) => activator.Create<T>(); 

var invoke_B_With_A = Expression.Lambda<Func<IActivator, TOut>>(
    Expression.Invoke(expressionB, 
     Expression.Invoke(builder, activatorParam), 
     Expression.Invoke(expressionA, activatorParam) 
    ), activatorParam); 
0

我想你需要的東西是這樣的:

var activator = Expression.Parameter(typeof(IActivator), "activator"); 
Expression<Func<IActivator,TOut>> invoke_B_With_A = 
    (Expression<Func<IActivator,TOut>>) Expression.Lambda(Expression.Invoke(expressionB, 
    activator, 
    Expression.Invoke(expressionA, activator) 
), new [] { activator }); 
+0

很少有查詢提供者實際上支持'Invoke'。所以這幾乎肯定會失敗,出於同樣的原因OP的代碼失敗。 – Servy

+0

接近但表達式B需要通過一個T的實例,這個解決方案缺少'activator.Create ()'位 – alastairtree

+0

@Servy我不認爲這裏涉及到任何查詢提供者,OP只是構造表達式來編譯和調用(我認爲)。還沒有提到的查詢提供者。 – Evk