2009-10-31 21 views
4

可能重复:
Comparing object properties in c#如何比较POCO之间的字段/属性?

比方说,我有一个POCO:

public class Person 
{ 
    public string Name { get; set; } 
    public DateTime DateOfBirth { get; set; } 
    public IList<Person> Relatives { get; set; } 
} 

我想比较人的两个实例,看看他们是否等于彼此。当然,我会比较Name,DateOfBirthRelatives集合以查看它们是否相等。但是,这将涉及我重写每个POCO的Equals()并手动编写每个字段的比较。

我的问题是,我该如何编写这个通用版本,所以我不必为每个POCO做?

回答

4

如果您不担心性能,你可以使用反射的效用函数来遍历每个字段,并比较它们的值。

using System; 
using System.Reflection; 


public static class ObjectHelper<t> 
{ 
    public static int Compare(T x, T y) 
    { 
     Type type = typeof(T); 
     var publicBinding = BindingFlags.DeclaredOnly | BindingFlags.Public; 
     PropertyInfo[] properties = type.GetProperties(publicBinding); 
     FieldInfo[] fields = type.GetFields(publicBinding); 
     int compareValue = 0; 


     foreach (PropertyInfo property in properties) 
     { 
      IComparable valx = property.GetValue(x, null) as IComparable; 
      if (valx == null) 
       continue; 
      object valy = property.GetValue(y, null); 
      compareValue = valx.CompareTo(valy); 
      if (compareValue != 0) 
       return compareValue; 
     } 
     foreach (FieldInfo field in fields) 
     { 
      IComparable valx = field.GetValue(x) as IComparable; 
      if (valx == null) 
       continue; 
      object valy = field.GetValue(y); 
      compareValue = valx.CompareTo(valy); 
      if (compareValue != 0) 
       return compareValue; 
     } 
    return compareValue; 
    } 
} 
+0

谢谢,我会尝试出你的代码。 – 2009-10-31 00:45:45

+0

嗯,我试了一下,但是'properties'和'fields'数组是空的。 – 2009-10-31 01:16:29

+0

找到原因。删除publicBinding变量,或者使用一些与DeclaredOnly或Public不同的枚举类型。 – 2009-10-31 01:44:22

1

可以使用反射来以一般方式完成此操作,但它具有性能和复杂性的缺点。手动实施EqualsGetHashCode会更好,因此您可以获得预期的结果。

Should I Overload == Operator?

1

实现Equals()和GetHashCode()没有太大的麻烦。

public override bool Equals(object obj) 
{ 
    if (ReferenceEquals(this, obj) return true; 
    if (!(obj is Person)) return false; 

    var other = (Person) obj; 
    return this == other; 
} 

public override int GetHashCode() 
{ 
    return base.GetHashCode(); 
} 

Using Equals/GetHashCode Effectively

+0

我很困惑。你的例子只是Equals()的默认行为。对于一个类而言,它可能不会太麻烦,但是当您需要将一堆样板代码添加到50个以上的类时,它确实成为一件麻烦事。 – 2009-11-07 00:09:13