2013-01-11 41 views
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; 

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

澄清

比方说,我开始是这样的表达式:

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

我有一个例程正在重建这一点,改变OrderDTO类型Order步行树和改变类型基于from/to类型的映射。这就是我做的,但产生的表达式

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

所以,当我重建树,我需要以某种指定返回类型 - 它看起来好像系统会自动确定返回类型,因为我没无论如何不要指定它。谢谢,Ray

+3

那么,什么是错与你最后体现在哪里? –

+0

这里并不完全清楚你在问什么,你问如何改变现有表达式树的返回类型?还是你问如何格式化你的lambda表达式,以便控制返回类型? – MattDavey

+1

'(Order o)=>(object)o.Customer'? –

回答

1

很难说没有真正看到你的代码,但它看起来像你使用的版本Expression.Lambda(),不让你指定创建的表达式的类型。如果你这样做,你是对的,代表类型将自动决定。

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

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); 
相关问题