Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing objects

Tags:

c#

I have a class it contains some string members, some double members and some array objects.

I create two objects of this class, is there any simplest, efficient way of comparing these objects and say their equal? Any suggestions?

I know how to write a compare function, but will it be time consuming.

like image 923
siva Avatar asked Dec 14 '10 05:12

siva


1 Answers

The only way you can really do this is to override bool Object.Equals(object other) to return true when your conditions for equality are met, and return false otherwise. You must also override int Object.GetHashCode() to return an int computed from all of the data that you consider when overriding Equals().

As an aside, note that the contract for GetHashCode() specifies that the return value must be equal for two objects when Equals() would return true when comparing them. This means that return 0; is a valid implementation of GetHashCode() but it will cause inefficiencies when objects of your class are used as dictionary keys, or stored in a HashSet<T>.

The way I implement equality is like this:

public class Foo : IEquatable<Foo>
{
    public bool Equals(Foo other)
    {
        if (other == null)
            return false;

        if (other == this)
            return true; // Same object reference.

        // Compare this to other and return true/false as appropriate.
    }

    public override bool Equals(Object other)
    {
        return Equals(other as Foo);
    }

    public override int GetHashCode()
    {
        // Compute and return hash code.
    }
}

A simple way of implementing GetHashCode() is to XOR together the hash codes of all of the data you consider for equality in Equals(). So if, for example, the properties you compare for equality are string FirstName; string LastName; int Id;, your implementation might look like:

public override int GetHashCode()
{
    return (FirstName != null ? FirstName.GetHashCode() : 0) ^
        (LastName != null ? LastName.GetHashCode() : 0) ^
        Id; // Primitives of <= 4 bytes are their own hash codes
}

I typically do not override the equality operators, as most of the time I'm concerned with equality only for the purposes of dictionary keys or collections. I would only consider overriding the equality operators if you are likely to do more comparisons by value than by reference, as it is syntactically less verbose. However, you have to remember to change all places where you use == or != on your object (including in your implementation of Equals()!) to use Object.ReferenceEquals(), or to cast both operands to object. This nasty gotcha (which can cause infinite recursion in your equality test if you are not careful) is one of the primary reasons I rarely override these operators.

like image 139
cdhowie Avatar answered Oct 14 '22 19:10

cdhowie