将两个表达式组合成一个管道

Eya*_*rry 4 c# expression combinators

我们假设我有以下两种表达方式:

Expression<Func<T, IEnumerable<TNested>>> collectionSelector;
Expression<Func<IEnumerable<TNested>, TNested>> elementSelector;
Run Code Online (Sandbox Code Playgroud)

有没有办法"组合"这些以形成以下:(?)

Expression<Func<T, TNested>> selector;
Run Code Online (Sandbox Code Playgroud)

编辑:

性能非常关键,因此如果可能的话,我会很高兴能够以极少的开销实现最佳解决方案.

非常感谢!

LmT*_*oon 7

static Expression<Func<A, C>> Foo<A, B, C>(
Expression<Func<B, C>> f,
Expression<Func<A, B>> g)
{
    var x = Expression.Parameter(typeof(A));
    return Expression.Lambda<Func<A, C>>(
        Expression.Invoke(f, Expression.Invoke(g, x)), x);
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,我无法访问计算机(这在性能方面是不好的解决方案).实际上,我认为您可以通过调用Expression来优化代码.

另一种方式似乎是(使用辅助功能):

Func<A, C> Foo<A,B,C>(Func<B, C> f, Func<A, B> g)
{ 
    return (A x) => f(g(x));
}
Run Code Online (Sandbox Code Playgroud)

然后你应该通过调用带有Foo函数的Expression来创建管道表达式.像那个伪代码:

   var expr1 = get expresstion<B,C> 
   var expr2 = get Expression<A, B>
   var foo = get method info of Foo method 
   specialize method with generic types A, B, C (via make generic method)
    return Expression.Call(foo, expr1, expr2);
Run Code Online (Sandbox Code Playgroud)