Given the two selector expressions, you must take the bindings from them MemberInitExpressionand create a new expression using all the bindings. But this expression will not work, because it uses two different parameter expressions for one parameter. We must also fix this.
Considering,...
Expression<Func<TSource, TResult>> left = ...
Expression<Func<TSource, TResult>> right = ...
... take the bindings ...
var leftInit = left.Body as MemberInitExpression;
var rightInit = right.Body as MemberInitExpression;
var bindings = leftInit.Bindings.Concat(rightInit.Bindings);
... create a new expression ...
var result = Expression.Lambda<Func<TSource, TResult>>(
Expression.MemberInit(Expression.New(typeof(TResult)), bindings), ???);
... , ...
var binder = new ParameterBinder(left.Parameters[0], right.Parameters[0]);
var bindings = binder.Visit(leftInit.Bindings.Concat(rightInit.Bindings));
, , :
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);
}
}
. , (: ), - :
var merged = columns.Apply(moreColumns);