简体   繁体   English

转换表达式 <Func<T, object> &gt;表达 <Func<object> &gt;

[英]Convert Expression<Func<T, object>> to Expression<Func<object>>

How to convert : Expression<Func<T, object>> to Expression<Func<object>> ? 如何转换: Expression<Func<T, object>>Expression<Func<object>>

For example: 例如:

public class Entity
{        
    public virtual long Id { get; set; }
}

Origin: 起源:

Expression<Func<Entity, object>> origin = x => x.Id;

Destination: 目的地:

Entity alias = null;
Expression<Func<object>> destination = () => alias.Id;

Reason: 原因:

Actually I'm trying to create a custom cacheable ResultTransformer for Nhibernate. 实际上,我正在尝试为Nhibernate创建一个自定义的可缓存ResultTransformer。 There is a method public QueryOverProjectionBuilder<T> WithAlias(Expression<Func<object>> alias); 有一个public QueryOverProjectionBuilder<T> WithAlias(Expression<Func<object>> alias); But in my classes for each particular entitites I would like to use more specific selector like Expression<Func<T, object>> 但是在我的类中,对于每个特定实体,我想使用更特定的选择器,例如Expression<Func<T, object>>

You have two options: 您有两种选择:

  1. Invoke the expression as Luaan suggested 按照Luaan的建议调用表达式
  2. Replace the parameters with the value you would like (a constant or a different expression) 将参数替换为所需的值(常数或其他表达式)

Option 1 is as simple as Expression.Invoke but may not be compatible with libraries such as LINQ. 选项1与Expression.Invoke一样简单,但可能与LINQ等库不兼容。 Option 2 is best done using an expression visitor: 选项2最好使用表达式访问者来完成:

    private class ExchangeParametersVisitor : ExpressionVisitor
    {
        public ParameterExpression Parameter { get; set; }
        public Expression Value { get; set; }

        protected override Expression VisitParameter(ParameterExpression node)
        {
            if (node == Parameter)
            {
                return Value;
            }
            return node;
        }
    }

What you need to do is apply the visitor to the body of your lambda expression and use it to create a new lambda expression that contains all parameters as before except the one you replaced. 您需要做的是将访问者应用于lambda表达式的主体,并使用它来创建一个新的lambda表达式,该表达式包含与之前相同的所有参数,但您替换的参数除外。

That's what Expression.Invoke is for. 这就是Expression.Invoke目的。

Create a new lambda expression, and use Expression.Invoke on the original expression to compose the two expressions. 创建一个新的lambda表达式,然后对原始表达式使用Expression.Invoke组成两个表达式。

Sample: 样品:

Expression<Func<string, int>> inner = x => int.Parse(x);
var outer = Expression.Lambda<Func<int>>
              (Expression.Invoke(inner, Expression.Constant("123")));

outer.Compile()().Dump(); // 123

Sadly, some expression parsers don't handle Invoke correctly - they assume it to be an invocation of a method, and reject it. 遗憾的是,某些表达式解析器无法正确处理Invoke他们认为它是方法的调用,并拒绝它。 In that case, you need to inline the expression. 在这种情况下,您需要内联表达式。 That means visiting the whole inner expression and replacing the ParameterExpression s with variables in the better case, or if parser doesn't support that either, inlining the argument in all the places. 这意味着访问整个内部表达式,并在更好的情况下用变量替换ParameterExpression ,或者如果解析器也不支持,则在所有位置插入参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何转换Expression Func <T, object[]> 到Func <T, object> - Howto convert Expression Func<T, object[]> to Func<T, object> 转换表达式 <Func<XClass, object> &gt;表达 <Func<YClass, object> &gt; - Convert Expression<Func<XClass, object>> to Expression<Func<YClass, object>> 无法从表达式转换 <Func<T1, T2> &gt;`到`Expression <Func<object, object> &gt;` - Cannot convert from `Expression<Func<T1, T2>>` to `Expression<Func<object, object>>` 如何转换 Linq 表达式<func<object,object,bool> &gt; 表达<func<t1,t2,bool> &gt; </func<t1,t2,bool></func<object,object,bool> - How to convert Linq Expression<Func<object,object,bool>> to Expression<Func<T1,T2,bool>> 转换表达式 <Func<TEntity,TKey> 表达 <Func<TEntity, Object> &gt; - Convert Expression<Func<TEntity,TKey> to Expression<Func<TEntity, Object>> 转换表达式 <Func<TDocument, object> &gt;表达 <Func<TDocument, TOutput> &gt; - Convert Expression<Func<TDocument, object>> to Expression<Func<TDocument, TOutput>> 如何转换表达式 <Func<TSource,string> &gt;表达 <Func<object,string> &gt; - How to convert Expression<Func<TSource,string>> to Expression<Func<object,string>> 转换表达式 <Func<T, TProperty> &gt;表达 <Func<object, object> &gt;反之亦然 - Convert Expression<Func<T, TProperty>> to Expression<Func<object, object>> and vice versa 如何将Expression <Func <T,DateTime >>转换为Expression <Func <T,object >> - How to cast Expression<Func<T, DateTime>> to Expression<Func<T, object>> 表达式的一般拆箱 <Func<T, object> &gt;表达 <Func<T, TResult> &gt; - Generic unboxing of Expression<Func<T, object>> to Expression<Func<T, TResult>>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM