准备动态Lambda表达式,检查parentproperty null控件

本文关键字:检查 parentproperty null 控件 表达式 动态 Lambda | 更新日期: 2023-09-27 18:13:49

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

我的问题是当我准备表达式像

MyClass1.Property2.ChildProperty1=="xyz";

如果Property2是null,那么我采取nullreference错误。

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;
}

另一个函数我执行我的请求,如" myfunc(myrequest);"

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

准备动态Lambda表达式,检查parentproperty null控件

你想动态地创建一个表达式体,像这样:

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变量包含可以用于比较谓词左侧的表达式。