2016-09-21 51 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