簡體   English   中英

表達式樹中的空傳播

[英]Null propagation in Expression Tree

請參見下面的示例代碼。 我如何修改它以處理空值,類似於?. 操作員工作?

class Program
{
    static LambdaExpression GetExpression(Expression<Func<string, string>> expr)
    {
        return expr;
    }

    static void Main(string[] args)
    {
        // I want to perform the following null propagation check
        // in the expression tree below.
        // (s as string)?.Replace("a", "o");

        var expr = GetExpression(t => t);

        var oldValue = Expression.Constant("a", typeof(string));
        var newValue = Expression.Constant("o", typeof(string));
        var mi = typeof(string).GetMethod(nameof(string.Replace), new[] { typeof(string), typeof(string) });

        var invoke = Expression.Invoke(expr, expr.Parameters);
        var call = Expression.Call(invoke, mi, oldValue, newValue);
        var lambda = Expression.Lambda(call, false, expr.Parameters);

        Console.WriteLine(lambda.Compile().DynamicInvoke("gaga"));

        // Should print empty line. Not throw!
        Console.WriteLine(lambda.Compile().DynamicInvoke(null));
    }
}

您必須做兩件事:

  1. 調用lambda.Compile().DynamicInvoke(null)是錯誤的。

    文檔指出該參數可以是:

    類型:System.Object []:
    對象數組,是要傳遞給當前委托表示的方法的參數。
    -要么-
    null ,如果當前委托表示的方法不需要參數。

    因此,通過傳遞null,您可以在不使用參數的情況下調用它,但是您想使用null字符串參數來調用它:

    這就是為什么您應該將此行更改為lambda.Compile().DynamicInvoke(new object[] {null})或簡單地將其lambda.Compile().DynamicInvoke((string)null)

  2. 您必須使用Expression.Condition添加一個空條件。

最終代碼:

var expr = GetExpression(t => t);
var oldValue = Expression.Constant("a", typeof(string));
var newValue = Expression.Constant("o", typeof(string));
var mi = typeof(string).GetMethod(nameof(string.Replace), new[] { typeof(string), typeof(string) });

var invoke = Expression.Invoke(expr, expr.Parameters);
var call = Expression.Call(invoke, mi, oldValue, newValue);

ConstantExpression nullConst = Expression.Constant(null, typeof(string));
var nullCondition = Expression.Condition(Expression.Equal(invoke, nullConst),
    nullConst, call);

var lambda = Expression.Lambda(nullCondition, false, expr.Parameters);

object result1 = lambda.Compile().DynamicInvoke("gaga"); // =="gogo"
object result2 = lambda.Compile().DynamicInvoke((string) null); //== null

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM