2016-09-21 82 views
1

我想用表达式树产生了这样一句话:表达式树邻.value的

o?.Value 

o是哪个类的一个实例。

有什么方法吗?

+1

你读过吗? http://stackoverflow.com/questions/28880025/why-cant-i-use-the-null-propagation-operator-in-lambda-expressions –

+0

我的意思是使用'Expression.constructors-like'方法。 – Jordi

回答

4

通常,如果您想要如何为某个表达式构建表达式树,请让C#编译器执行该操作并检查结果。

但在这种情况下,它不起作用,因为“表达式树lambda可能不包含空传播运算符。”但是你实际上并不需要空传播运算符,你只需要一些行为像一样的东西。

你可以通过创建一个如下所示的表达式来实现:o == null ? null : o.Value。在代码中:

public Expression CreateNullPropagationExpression(Expression o, string property) 
{ 
    Expression propertyAccess = Expression.Property(o, property); 

    var propertyType = propertyAccess.Type; 

    if (propertyType.IsValueType && Nullable.GetUnderlyingType(propertyType) == null) 
     propertyAccess = Expression.Convert(
      propertyAccess, typeof(Nullable<>).MakeGenericType(propertyType)); 

    var nullResult = Expression.Default(propertyAccess.Type); 

    var condition = Expression.Equal(o, Expression.Constant(null, o.Type)); 

    return Expression.Condition(condition, nullResult, propertyAccess); 
} 
+0

就像'o == null? null:o.Value',而不像'o?.Value',这会导致o被评估两次,如果编译为IL,对吧?如果是这样,那可能应该提到。 – hvd

+2

@ hvd是的。我默默地认为它没问题,因为评估一个简单的表达式'o'两次不应该导致任何问题。如果你想避免这种情况,你可以创建一个Block,它首先将'o'分配给一个临时变量,然后使用该变量。 (虽然如果你想在某些LINQ提供程序中使用这个表达式,这可能不起作用。) – svick

+0

你已经评论说,如果你想要如何为某个表达式构建表达式树,你让C#编译器执行它并检查结果_。我想问你如何检查这些。 – Jordi