我会这样:
编写一个参数替换表达式访问者,该访问者可以如下 *** 作原始表达式:
- 完全从lambda签名中删除不需要的参数。
- 将参数的所有使用替换为所需的索引器表达式。
这是我根据先前对另一个问题的回答得出的快速而肮脏的示例:
public static class ParameterReplacer{ // Produces an expression identical to 'expression' // except with 'source' parameter replaced with 'target' expression. public static expression<TOutput> Replace<TInput, TOutput> (expression<TInput> expression, Parameterexpression source, expression target) { return new ParameterReplacerVisitor<TOutput>(source, target) .VisitAndConvert(expression); } private class ParameterReplacerVisitor<TOutput> : expressionVisitor { private Parameterexpression _source; private expression _target; public ParameterReplacerVisitor (Parameterexpression source, expression target) { _source = source; _target = target; } internal expression<TOutput> VisitAndConvert<T>(expression<T> root) { return (expression<TOutput>)VisitLambda(root); } protected override expression VisitLambda<T>(expression<T> node) { // Leave all parameters alone except the one we want to replace. var parameters = node.Parameters.Where(p => p != _source); return expression.Lambda<TOutput>(Visit(node.Body), parameters); } protected override expression VisitParameter(Parameterexpression node) { // Replace the source with the target, visit other params as usual. return node == _source ? _target : base.VisitParameter(node); } }}
您的方案的使用情况(已测试):
var zeroIndexIndexer = expression.MakeIndex (expression.Constant(foos), typeof(List<Foo>).GetProperty("Item"), new[] { expression.Constant(0) });// .ToString() of the below looks like the following: // () => (value(System.Collections.Generic.List`1[App.Foo]).Item[0].a// * value(System.Collections.Generic.List`1[App.Foo]).Item[0].b)var exp1Clone = ParameterReplacer.Replace<Func<Foo, int>, Func<int>> (exp0, exp0.Parameters.Single(), zeroIndexIndexer);
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)