转换前pression< Func键< FromType>>到防爆pression< Func键< ToType>> [英] Convert Expression<Func<FromType>> to Expression<Func<ToType>>

查看:158
本文介绍了转换前pression< Func键< FromType>>到防爆pression< Func键< ToType>>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怎样才能让一个普通的辅助方法,转换使用的函数功能从一种类型到另一种内的防爆pression类型

How can I make a generic helper method to convert the type used by a Func from one type to another within an Expression

我有一个防爆pression< Func键< IEmployee,布尔>> ,我想将其转换为一个

I have a Expression<Func<IEmployee, bool>> and I want to convert it to a

Expression<Func<Employee, bool>>.

第二类始终贯彻的第一个类型。一个通用的解决方案是什么,我想要的目的。

The second Type always implements the first Type. A generic solution is what I am trying to achieve.

修改

我已经编辑了问题再清楚不过了。

I have edited the question to be clearer.

推荐答案

好了,你可以创建一个前pression是蒙上,然后转发其参数原来的EX pression:

Well, you could create an expression that casts and then forwards its argument to the original expression:

Expression<Func<IEmployee, bool>> source = ...

var param = Expression.Parameter(typeof(Employee));

// Types the argument as the type expected by the source expression
// and then forwards it...
var invocationExpr = Expression.Invoke
                     (source, Expression.TypeAs(param, typeof(IEmployee))); 

var result = Expression.Lambda<Func<Employee, bool>>(invocationExpr, param);

如果供应商不支持调用EX pressions,你可能需要一个更 成熟的解决方案,替代参数源EX pression。

If the provider doesn't support invocation expressions, you will probably need a much more sophisticated solution that replaces Parameters in the source expression.

编辑:好吧,既然你说你的供应商不喜欢所得到的前pression,这里的替代的一个例子。这是一个的真正的一个什么样的参数替代应该像粗剪(我只是写了这个,现在为样本),但它应该能正常运行你的目的。

Ok, since you say your provider doesn't like the resulting expression, here's an example of the alternative. It's a really rough cut of what a parameter-replacer should look like (I just wrote this now as a sample), but it should work fine for your purposes.

public static class ParameterReplacer
{
    // Produces an expression identical to 'expression'
    // except with 'source' parameter replaced with 'target' parameter.     
    public static Expression<TOutput> Replace<TInput, TOutput>
                 (Expression<TInput> expression,
                  ParameterExpression source,
                  ParameterExpression target)
    {
        return new ParameterReplacerVisitor<TOutput>(source, target)
                  .VisitAndConvert(expression);
    }

    private class ParameterReplacerVisitor<TOutput> : ExpressionVisitor
    {
        private ParameterExpression _source;
        private ParameterExpression _target;

        public ParameterReplacerVisitor
              (ParameterExpression source, ParameterExpression 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.Select
                             (p => p == _source ? _target : p);

            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);
        }
    }
}

,然后用它为:

And then use it as:

Expression<Func<IEmployee, bool>> expression = ...

var result = ParameterReplacer.Replace
                <Func<IEmployee, bool>, Func<Employee, bool>>
                (expression,
                 expression.Parameters.Single(), 
                 Expression.Parameter(typeof(Employee));

这篇关于转换前pression&LT; Func键&LT; FromType&GT;&GT;到防爆pression&LT; Func键&LT; ToType&GT;&GT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆