5

Possible Duplicate:
Comparing object properties in c#

Let's say I have a POCO:

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

I want to compare two instances of Person to see if they're equal to each other. Naturally, I would compare Name, DateOfBirth, and the Relatives collection to see if they're equal. However, this would involve me overriding Equals() for each POCO and manually writing the comparison for each field.

My question is, how can I write a generic version of this so I don't have to do it for each POCO?

4

3 に答える 3

5

パフォーマンスについて心配していない場合は、ユーティリティ関数でリフレクションを使用して、各フィールドを反復処理し、それらの値を比較できます。

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; 
    } 
}
于 2009-10-31T00:10:03.423 に答える
2

リフレクションを使用して一般的な方法でこれを行うことは可能ですが、パフォーマンスと複雑さの欠点があります。期待どおりの結果が得られるようにEquals、手動で実装する方がはるかに優れています。GetHashCode

== 演算子をオーバーロードする必要がありますか? を参照してください。

于 2009-10-31T00:09:57.323 に答える
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();
}

Equals/GetHashCode の効果的な使用を参照してください。

于 2009-10-31T09:28:25.550 に答える