C# 使用检查parentproperty null控件准备动态Lambda表达式
我有一个动态lambda表达式树,我准备我的表达式并编译它 我的问题是当我准备表达的时候C# 使用检查parentproperty null控件准备动态Lambda表达式,c#,linq,lambda,expression,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 {
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;
}
公共类MyClass1
{
公共字符串属性1{get;set;}
公共MyClass2属性2{get;set;}
}
公共类MyClass2
{
公共字符串ChildProperty1{get;set;}
公共字符串ChildProperty2{get;set;}
}
公共函数编译器(规则r)
{
...
Func myfunc=Expression.Lambda(expr,paramUser).Compile();
...
返回myfunc;
}
我执行请求的另一个函数,如“myfunc(myrequest);”
当我在CompileTime中输入表达式时,是否有一种检查null控件的通用方法,如果ParentProperty为null,则为这些语句返回false?在compile方法中,我没有实体,因此我必须使用check null control来准备语句,所以您希望动态创建一个表达式体,如下所示:
Expression<Func<MyClass1, string>> expr =
x => x.Property2?.ChildProperty1;
这不是完全等效的,但应该有效
下面是一个示例代码段,它动态地执行此操作:
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);
}
}
string memberPath=…;//e、 g.“财产2.儿童财产2”
var参数=表达式参数(类型为(T),“x”);
表达结果;
if(memberPath.IndexOf('.')<0)
结果=Expression.PropertyOrField(参数,memberPath);
其他的
{
var memberNames=memberPath.Split('.');
var members=新表达式[memberNames.Length];
for(int i=0;i0?members[i-1]:参数,memberNames[i]);
结果=成员[members.Length-1];
//对于不可为null的值类型,将结果升级为相应的可为null的类型
if(result.Type.IsValueType&&null.getUnderlinegType(result.Type)==null)
result=Expression.Convert(result,typeof(Nullable).MakeGenericType(result.Type));
var nullResult=Expression.Constant(null,result.Type);
对于(int i=members.Length-2;i>=0;i--)
{
结果=表达式。条件(
Expression.NotEqual(成员[i],Expression.Constant(null)),
结果,结果),;
}
}
最后,
result
变量包含可用于比较谓词左侧的表达式。不太清楚您在问什么,但可以使用C#6中的null条件运算符:MyClass1?.Property2?.ChildProperty==“xyz”
。如果MyClass1
为null,或者MyClass1.Property2
为null,则返回false。这就是你想要的吗?是的,我想这样做,但是我动态地准备这个语句。有没有一种通用的方法来准备我的表达式,比如。expression.Constant(r.TargetValue,typeof(string))和expression.Equal(expression.Property(parameter,item.Key),expression.Constant(item.Value))@j0ey_wh:您没有格式化代码-您取消了我上次编辑的格式化。根本不清楚r.TargetValue
、参数
、项.Key
或项.Value
是什么。从代码的早期开始,看起来您使用的是lambda表达式,但现在听起来好像不是。我们无法真正帮助你,因为我们不得不猜测你想要实现什么。请将其编辑成一个。我在运行时创建动态lambda表达式,并编译它,然后执行。如果父属性为null,则我希望在表达式中添加null检查,而不是在父属性为null时我接受null引用错误。当我准备表达式时,我使用c#lambda方法,如expression.Equal,Expression.constant类似于Expression.MakeBinary(tBinary,propExpression,right)作为结果{(Param_0.Body.No==6)},我如何与这些表达式组合。我尝试了一下,但得到了二进制运算符,并且也没有为类型“System.Nullable`1[System.Int32]”和“System.Boolean”定义。var a=AccessMember(r.MemberName,paramExp);var b=Expression.MakeBinary(tBinary,propExpression,right),Expression.AndAlso(a,b);您可能需要将right
转换为left
的类型。例如if(right.type!=left.type)right=Expression.convert(right,left.type)
I转换但仍然得到二进制运算符,并且没有为类型“System.Nullable1[System.Int32]”和“System.Nullable
1[System.Int32]”定义错误它们不应该是int
(或Nullable
)表达式类型。AndAlso
需要bool
表达式。在您的示例中,a
应该是left
,如果right
转换为left
类型,var b=expression.MakeBinary(tBinary,left,right),
应该是bool
类型。如果你发布完整的代码,我可以看一下。
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);
}
}