C# 表达式树、对象比较器
我需要生成表达式树,然后检查两个对象(参数)是否相等。我知道这些对象会有属性,所以我必须比较它们的值,怎么做? 因此,我有类似于C# 表达式树、对象比较器,c#,expression-trees,C#,Expression Trees,我需要生成表达式树,然后检查两个对象(参数)是否相等。我知道这些对象会有属性,所以我必须比较它们的值,怎么做? 因此,我有类似于obj1,obj2的内容,以及需要检查属性名的字符串数组。 我是这样看的: var leftObject = E.Parameter(typeof (object), "leftObject"); var rightObject = E.Parameter(typeof (object), "rightObject"); var properties = E.Param
obj1
,obj2
的内容,以及需要检查属性名的字符串数组。
我是这样看的:
var leftObject = E.Parameter(typeof (object), "leftObject");
var rightObject = E.Parameter(typeof (object), "rightObject");
var properties = E.Parameter(typeof (string[]), "properties");
var i = E.Parameter(typeof(int), "i");
var equal = E.Parameter(typeof (bool), "equal");
var body = E.Block
(
new[] { properties, i},
E.Assign(properties,E.Constant(props)),
E.Assign(i,E.Constant(0)),
E.Assign(equal,E.Constant(true)),
E.Loop
(
E.Property(leftObject,props[i]) == E.Property(rightObject,props[i])
)
);
如何实现在循环中逐个访问属性
p.S.
E
是我对表达式的别名
可能是这样的:可能是这样的:你可以使用反射来实现这一点
bool eq = true;
foreach (string prop in PropertiesYouWantToCheck){
PropertyInfo propInfo = obj1.GetType().GetProperties().Single(x => x.Name == prop);
if(propInfo.GetValue(obj1, null) != propInfo.GetValue(obj2, null)){
eq = false;
break;
}
}
如果使用上述方法,请确保将字符串强制转换为字符串而不是对象
string[] props = null;
var leftObject = Expression.Parameter(typeof(object), "leftObject");
var rightObject = Expression.Parameter(typeof(object), "rightObject");
var equal = Expression.Variable(typeof(bool), "equal");
var lbl = Expression.Label();
var returnTarget = Expression.Label();
var body = Expression.Block
(
typeof(bool),
equal,
Expression.Assign(equal, Expression.Constant(true)),
Expression.Block(
props.Select(property =>
Expression.IfThen(
Expression.NotEqual(Expression.Property(leftObject, property),
Expression.Property(rightObject, property)),
Expression.Block(
Expression.Assign(equal, Expression.Constant(false)),
Expression.Goto(lbl)
)
)
)
),
Expression.Label(lbl),
Expression.Return(returnTarget, equal, typeof(bool)),
Expression.Label(returnTarget)
);
您可以使用反射来实现这一点
bool eq = true;
foreach (string prop in PropertiesYouWantToCheck){
PropertyInfo propInfo = obj1.GetType().GetProperties().Single(x => x.Name == prop);
if(propInfo.GetValue(obj1, null) != propInfo.GetValue(obj2, null)){
eq = false;
break;
}
}
如果使用上述方法,请确保将字符串强制转换为字符串而不是对象
string[] props = null;
var leftObject = Expression.Parameter(typeof(object), "leftObject");
var rightObject = Expression.Parameter(typeof(object), "rightObject");
var equal = Expression.Variable(typeof(bool), "equal");
var lbl = Expression.Label();
var returnTarget = Expression.Label();
var body = Expression.Block
(
typeof(bool),
equal,
Expression.Assign(equal, Expression.Constant(true)),
Expression.Block(
props.Select(property =>
Expression.IfThen(
Expression.NotEqual(Expression.Property(leftObject, property),
Expression.Property(rightObject, property)),
Expression.Block(
Expression.Assign(equal, Expression.Constant(false)),
Expression.Goto(lbl)
)
)
)
),
Expression.Label(lbl),
Expression.Return(returnTarget, equal, typeof(bool)),
Expression.Label(returnTarget)
);
您应该使用反射来发现您想要的属性,然后基本上创建一个大系列的AndAlso表达式。 e、 g
这并不是一个完整的解决方案,因为它假设您希望比较所有属性,并且所有属性都是可读的,但它应该可以帮助您找到正确的方法。如果你关心这些事情,它也是.NET3.5兼容的 您应该使用反射来发现您想要的属性,然后基本上创建一大系列AndAlso表达式。 e、 g
这并不是一个完整的解决方案,因为它假设您希望比较所有属性,并且所有属性都是可读的,但它应该可以帮助您找到正确的方法。如果你关心这些事情,它也是.NET3.5兼容的 谢谢。我已经用反射完成了,但是速度太慢了,所以我决定为不同的对象生成比较方法并将它们存储在内存中,然后检查预设类型的比较方法是否存在并调用它。它比反射快上百倍,因为每个需要比较的类型都要编译表达式一次。谢谢。我已经用反射完成了,但速度非常慢,所以我决定为不同的对象生成比较方法,并将编译后的方法存储在内存中,然后我检查预置类型的比较方法是否存在,并调用它。它比反射快一百倍,因为每个需要比较的类型都会编译一次表达式。