Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 表达式树、对象比较器_C#_Expression Trees - Fatal编程技术网

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兼容的

谢谢。我已经用反射完成了,但是速度太慢了,所以我决定为不同的对象生成比较方法并将它们存储在内存中,然后检查预设类型的比较方法是否存在并调用它。它比反射快上百倍,因为每个需要比较的类型都要编译表达式一次。谢谢。我已经用反射完成了,但速度非常慢,所以我决定为不同的对象生成比较方法,并将编译后的方法存储在内存中,然后我检查预置类型的比较方法是否存在,并调用它。它比反射快一百倍,因为每个需要比较的类型都会编译一次表达式。