表达式树 C# - 空条件运算符 (?.)

Expression Tree C# - Null-Conditional oeprator (?.)

我正在尝试构建等效于“?”的表达式树。运算符。

var member = Expression.Property(Expression.Property("PropertyObjectName", value.Property), 
    "PropertyOfObject");

即:member.PropertyObjectName.PropertyOfObject 如果 PropertyObjectName 是我想避免的 null,那当然会 抛出 Null exception .

除了把 ConditionalExpression 放在那里之外,还有什么方法可以构建 member?.PropertyObjectName?.PropertyOfObject 吗?

你可以使用我的扩展方法

public static class ExpressionExtensions
    {
        public static Expression ElvisOperator(this Expression expression, string propertyOrField)
        {
            return Expression.Condition(Expression.NotEqual(expression, Expression.Constant(null)),
                Expression.PropertyOrField(expression, propertyOrField),
                Expression.Constant(null, expression.Type)
                );
        }
    }

这会生成类似

的内容
IIF((x != null), x.propertyname, null)

那么你可以这样使用它:

public class TestClass
    {
        public int FirstProp { get; set; }

        public TestClass SecondProp { get; set; } 
    }


var variable = Expression.Parameter(typeof(TestClass), "x");
var nullSafe = variable.ElvisOperator("SecondProp");

我做了这个测试:

List<TestClass> tests = new List<TestClass>(){
            new TestClass() { FirstProp = 1, SecondProp = new TestClass() { SecondProp = new TestClass() } },
            new TestClass() { FirstProp = 2 },
            new TestClass() { FirstProp = 3, SecondProp = new TestClass() },
            new TestClass() { FirstProp = 4 },
        };

        var variable = Expression.Parameter(typeof(TestClass), "x");
        var nullSafe = variable.ElvisOperator("SecondProp").ElvisOperator("SecondProp");
        var cond = Expression.NotEqual(nullSafe, Expression.Constant(null, variable.Type));

        var lambda = Expression.Lambda<Func<TestClass, bool>>(cond, new ParameterExpression[] { variable });

        tests = tests.AsQueryable().Where(lambda).ToList();

        Console.WriteLine(tests.Count);

这会在控制台上打印 1,因为这样过滤列表:

.Where(x => x.SecondProp?SecondProp != null)