2

如果我手动构建表达式树,运行时似乎会自动确定返回类型。因此,如果我构建一个如下所示的表达式树:

// Order contains a navigation property for Customer
(Order o) => o.Customer;

运行时将返回类型确定为客户,本质上是这样的:

Expression<Func<Order, Customer>> efd = (Order o) => o.Customer;

我如何构建它 - 或更改我构建的内容,因此返回是对象,即表达式为:

Expression<Func<Order, object>> ef = (Order o) => o.Customer;

这是通用的,我在编译时不知道返回类型是 Customer;它可以是(在这种情况下)订单中的任何导航属性。

澄清

假设我从这样的表达式开始:

Expression<Func<OrderDTO, object>> ef = (OrderDTO o) => o.Customer;

我有一个例程正在重建它,通过遍历树来更改类型,OrderDTOOrder根据从/到类型的映射更改类型。这就是我所做的一切,但结果表达式是

Expression<Func<Order, Customer>> ef = (Order o) => o.Customer;

因此,当我重建树时,我需要以某种方式指定返回类型 - 看起来系统正在自动确定返回类型,因为我没有指定它。谢谢,雷

4

2 回答 2

1

如果没有实际看到您的代码,很难说,但看起来您使用的版本Expression.Lambda()不允许您指定创建的表达式的类型。如果你这样做,那么委托类型将自动决定是对的。

要解决此问题,您需要使用Expression.Lambda()允许您使用类型参数(例如Expression.Lambda<Func<Order, object>>(…))指定委托类型的版本,或者在您的情况下更可能的是,将委托类型指定为类型的普通参数的版本TypeExpression.Lambda(funcType, …))。

于 2013-01-14T19:51:02.273 回答
0
public class ReturnTypeVisitor<TSource, TReturnValue> : ExpressionVisitor{

    protected override Expression VisitLambda<T>(Expression<T> node)
    {
        var delegateType = typeof(Func<,>).MakeGenericType(typeof(TSource), typeof(TReturnValue));
        return Expression.Lambda(delegateType, Visit(node.Body), node.Parameters);
    }

    protected override Expression VisitMember(MemberExpression node)
    {
        if (node.Member.DeclaringType == typeof(TSource))
        {
            return Expression.Property(Visit(node.Expression), node.Member.Name);
        }
        return base.VisitMember(node);
    }
}

用法:

public class Foo{
    public Bar Bar { get; set; }
}

public class Bar { }

Expression<Func<Foo, object>> expression = p => p.Bar;
Expression<Func<Foo, Bar>> stronglyTypedReturnValue =(Expression<Func<Foo, Bar>>) new ReturnTypeVisitor<Foo, Bar>().Visit(expression);
于 2017-02-03T04:15:28.170 回答