对聚合表达式进行空检查

时间:2019-01-08 16:45:05

标签: c# expression-trees

我有一个表达式助手来帮助从对象层次结构中获取值

   public static Func<T, object> GetMemberExpressionFunc<T>(string expressionString)
   {
     if (string.IsNullOrEmpty(expressionString))
     {
         throw new InvalidOperationException("invalid Expression");
     }

     var parameter = Expression.Parameter(typeof(T));
     Expression memberExpression = parameter;
     var tokens = expressionString.Split('.');
     memberExpression = tokens.Aggregate(memberExpression, Expression.PropertyOrField);

     var convertExpression = Expression.Convert(memberExpression, typeof(object));
     return Expression.Lambda<Func<T, object>>(convertExpression, parameter)
                        .Compile();

    }

用法

public class A
{
        public B BObj { get; set; }
}

public class B
{
        public string Name { get; set; }

}

 static void Main(string[] args)
 {
   var obj = new A {BObj = new B {Name ="Test"}};
   var obj2 = new A ();

   var exp = ExpressionHelper.GetMemberExpressionFunc<A>("BObj.Name");

  var test1 =  exp(obj);// test1 is "Test"

  var test2 = exp(obj2); //throws because BObj is null
}

如果层次结构中的任何属性为null,而不是引发异常,我希望表达式返回null。可以在聚合表达式上执行此操作吗?

1 个答案:

答案 0 :(得分:5)

在这种情况下,

C#空条件运算符?.会非常方便。不幸的是,表达式树仍然不支持它,因此一种实现此目标的方法是动态构建等同于手动空值检查的所有方式:

x => x != null && x.Prop1 != null && x.Prop1.Prop2 != null ... ? (object)x.Prop1.Prop2...PropN : null

由于您需要聚合成员访问器表达式和要在最终Expression.Condition中使用的条件,因此Aggregate方法并不好-用旧的{{1} }循环看起来更合适,例如:

foreach