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

时间:2019-07-11 07:23:11

标签: c# expression-trees system.reflection

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

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

这是:member.PropertyObjectName.PropertyOfObject,如果Null exceptionPropertyObjectName,那我当然会抛出 null

除了放置member?.PropertyObjectName?.PropertyOfObject之外,还有什么方法可以构建ConditionalExpression

1 个答案:

答案 0 :(得分:0)

您可以使用我的扩展方法

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)