开发者

How do I compare the fields/properties between POCOs? [duplicate]

This question already has answers here: Closed 10 years ago.

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 collectio开发者_开发百科n 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?


If you are not worried about performance, you could use reflection in a utility function to iterate over each field and compare their values.

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; 
    } 
}


It is possible to use reflection to do this in a general way, but it has performance and complexity drawbacks. It's much better to implement Equals and GetHashCode manually so that you get the results you expect.

See Should I Overload == Operator?


Implementing Equals() and GetHashCode() isn't much hassle.

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();
}

See Using Equals/GetHashCode Effectively

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜