Это во многом зависит, какие поставщики должны использовать его. Некоторое будет хорошо:
public static Expression<Func<TSource, TReturn>>
Merge<TSource, TSource2, TReturn>(
Expression<Func<TSource, TSource2>> foo1,
Expression<Func<TSource2, TReturn>> foo2)
{
return Expression.Lambda<Func<TSource, TReturn>>(
Expression.Invoke(foo2, foo1.Body),
foo1.Parameters);
}
Однако, другие (EF) не будут. Вы также можете переписать дерево выражений с посетителем, чтобы вставить выражение:
public static Expression<Func<TSource, TReturn>>
Merge<TSource, TSource2, TReturn>(
Expression<Func<TSource, TSource2>> foo1,
Expression<Func<TSource2, TReturn>> foo2)
{
var swapped = new SwapVisitor(
foo2.Parameters.Single(), foo1.Body).Visit(foo2.Body);
return Expression.Lambda<Func<TSource, TReturn>>(
swapped, foo1.Parameters);
}
class SwapVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public SwapVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
это будет работать со всеми поставщиками.
Вы можете добавить конкретный пример, который показывает, что вы имеете в виду? это как в 'x => x.Name' и' s => s.Length', чтобы получить 'x => x.Name.Length'? –
Да, извините, это то, что я имел в виду, для будущей справки, когда люди приходят к этому. – Tim