2009-10-31 57 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