給定兩個「選擇」的表達,你從他們的MemberInitExpression
採取綁定,並使用所有綁定一個新的表達式。但是這個表達式不起作用,因爲它爲一個參數使用了兩個不同的參數表達式。我們也需要解決這個問題。
鑑於...
Expression<Func<TSource, TResult>> left = ... // columns
Expression<Func<TSource, TResult>> right = ... // more columns
...走...綁定
var leftInit = left.Body as MemberInitExpression;
var rightInit = right.Body as MemberInitExpression;
var bindings = leftInit.Bindings.Concat(rightInit.Bindings);
...創建一個新的表達......
var result = Expression.Lambda<Func<TSource, TResult>>(
Expression.MemberInit(Expression.New(typeof(TResult)), bindings), ???);
.. .BUT,需要單參數...
var binder = new ParameterBinder(left.Parameters[0], right.Parameters[0]);
var bindings = binder.Visit(leftInit.Bindings.Concat(rightInit.Bindings));
// now, just use right.Parameters[0] as parameter...
而且,替換參數的效果很好使用表達式訪問者:
class ParameterBinder : ExpressionVisitor
{
readonly ParameterExpression parameter;
readonly Expression replacement;
public ParameterBinder(ParameterExpression parameter, Expression replacement)
{
this.parameter = parameter;
this.replacement = replacement;
}
protected override Expression VisitParameter(ParameterExpression node)
{
if (node == parameter)
return replacement;
return base.VisitParameter(node);
}
}
這個抽象的東西水暖工作得很好。事實上,你可以只使用一個existing library(擾流板:我是作者),這應該引起類似的東西:
var merged = columns.Apply(moreColumns);
http://stackoverflow.com/questions/16516971/linq-dynamic-select –
'columns = d => {var c = columns(); c.OtherProperty = d.OtherProperty;返回c; }'?請更具體地說明您嘗試過的內容,以及您遇到的具體問題。你的問題目前非常廣泛。 –
你不覺得我已經做到了嗎?看起來你沒有測試,因爲你得到這個錯誤。 '帶有語句正文的lambda表達式不能轉換爲表達式樹' –