使用检查parentproperty空控件准备动态Lambda表达式

时间:2016-10-19 11:06:43

标签: c# linq lambda expression

我有动态lambda表达式树,我准备我的表达式并编译它。

我的问题是当我准备类似

的表达式时
MyClass1.Property2.ChildProperty1=="xyz";

如果Property2为null,则我将nullrefence错误。

public class MyClass1
{
    public string Property1{get;set;}
    public MyClass2 Property2{get;set;}
}

public class MyClass2
{
    public string ChildProperty1{get;set;}
    public string ChildProperty2{get;set;}
}

public Func<T, bool> CompileRule<T>(Rule r)
{
     ...
     Func<T, bool> myfunc =Expression.Lambda<Func<T, bool>>(expr, paramUser).Compile();
     ...
     return myfunc;
}

我执行我的请求的另一个功能,如&#34; MYFUNC(myrequest); &#34;

当我在CompileTime中预表达我的表达式时是否有通用的方法来检查空控制,如果ParentProperty为null然后为这些语句返回false?在编译方法中我没有实体,所以我必须准备带有check null控件的语句

1 个答案:

答案 0 :(得分:2)

所以你想动态创建一个表达式的主体:

Expression<Func<MyClass1, string>> expr = 
    x => x.Property2?.ChildProperty1;

不幸的是,目前还没有支持这种标准的Expression方法。如果您尝试以上操作,则会出现编译时错误:

  
    

错误CS8072表达式树lambda可能不包含空传播运算符。

  

一种可能的方法是生成这样的表达式的主体:

Expression<Func<MyClass1, string>> expr = 
    x => x.Property2 != null ? x.Property2.ChildProperty1 : null;

这不是确切的等价物,但应该有效。

以下是动态执行此操作的示例代码段:

string memberPath = ...; // e.g. "Property2.ChildProperty2"
var parameter = Expression.Parameter(typeof(T), "x");
Expression result;
if (memberPath.IndexOf('.') < 0)
    result = Expression.PropertyOrField(parameter, memberPath);
else
{
    var memberNames = memberPath.Split('.');
    var members = new Expression[memberNames.Length];
    for (int i = 0; i < memberNames.Length; i++)
        members[i] = Expression.PropertyOrField(i > 0 ? members[i - 1] : parameter, memberNames[i]);
    result = members[members.Length - 1];
    // For non nullable value types, promote the result into the corresponding nullable type
    if (result.Type.IsValueType && Nullable.GetUnderlyingType(result.Type) == null)
        result = Expression.Convert(result, typeof(Nullable<>).MakeGenericType(result.Type));
    var nullResult = Expression.Constant(null, result.Type);
    for (int i = members.Length - 2; i >= 0; i--)
    {
        result = Expression.Condition(
            Expression.NotEqual(members[i], Expression.Constant(null)),
            result, nullResult);
    }
}

最后,result变量包含可用于比较谓词左侧的表达式。