views:

666

answers:

3

Say you have two different classes where each have their own implementation of Equals; which one is used? What if only one of them have one? Or none of them? Are any of the following lines equivalent?

object .Equals( first, second )
first .Equals( second )
second .Equals( first )

I'm guessing that the first two might be equivalent, but I don't really have a clue.

What does it really do?

+13  A: 

Basically it does three things:

  • Check for reference equality (return true if so)
  • Check for reference nullity (return false if either value is null; by now the null == null case has been handled)
  • Check for value equality with first.Equals(second)

The ordering shouldn't matter if both values have well-behaved equality implementations, as equality should be implemented such that x.Equals(y) implies y.Equals(x). However, the offline documentation I've got installed does state that first.Equals(second) (or objA.equals(objB) to use the real parameter naming) is specified. The online documentation doesn't mention this, interestingly enough.

Just to make all of this concrete, the implementation could look like this:

public static bool Equals(object x, object y)
{
    if (x == y) // Reference equality only; overloaded operators are ignored
    {
        return true;
    }
    if (x == null || y == null) // Again, reference checks
    {
        return false;
    }
    return x.Equals(y); // Safe as we know x != null.
}
Jon Skeet
+1  A: 

By default, object equivalency is determined by the object's address in memory. If both instances have the same memory address, they are equal.

However, this can be overloaded within the object so that developers can compare two objects that arn't in the same memory location and still be considered equal. For example, if you had a Data Access Layer where each object had its data record's ID from the database, you could have object equality compared based on the ID.

You can overload operators to produce this functionality.

Soviut
You can't override operators in C#. You can *overload* operators, or *override* the Equals method.
Jon Skeet
Thanks, fixed it.
Soviut
A: 

Well!!! implementation of Equals supports reference equality for reference types, and bitwise equality for value types. Reference equality means the object references that are compared refer to the same object. Bitwise equality means the objects that are compared have the same binary representation.

Note that a derived type might override the Equals method to implement value equality. Value equality means the compared objects have the same value even though they have different binary representations. For example, consider two Decimal objects that represent the numbers 1.10 and 1.1000. The Decimal objects do not have bitwise equality because they have different binary representations to account for the different number of trailing zeroes. However, the objects have value equality because the numbers 1.10 and 1.1000 are considered equal for comparison purposes since the trailing zeroes are insignificant.

Notes to Implementers

This method can be overridden by a derived class. For example, many of the base data types return true if both objects represent the same value; otherwise, false.

This method only compares primitives and objects. It must be overridden to compare more complex structures, such as arrays of objects.

The following statements must be true for all implementations of the Equals method. In the list, x, y, and z represent object references that are not null.

*

  x.Equals(x) returns true, except in cases that involve floating-point types. See IEC 60559:1989, Binary Floating-point Arithmetic for Microprocessor Systems.
*

  x.Equals(y) returns the same value as y.Equals(x).
*

  x.Equals(y) returns true if both x and y are NaN.
*

  (x.Equals(y) && y.Equals(z)) returns true if and only if x.Equals(z) returns true.
*

  Successive calls to x.Equals(y) return the same value as long as the objects referenced by x and y are not modified.
*

  x.Equals(null) returns false.

See GetHashCode for additional required behaviors pertaining to the Equals method.

Implementations of Equals must not throw exceptions.

You can compare the current object to another object for reference equality by using the this keyword in C# (for example, if (this == otherObj)) or the Me keyword in Visual Basic (for example, If Me Is otherObject Then …).

For some kinds of objects, it is desirable to have Equals test for value equality instead of referential equality. Such implementations of Equals return true if the two objects have the same "value", even if they are not the same instance. The type's implementer decides what constitutes an object's "value", but it is typically some or all the data stored in the instance variables of the object. For example, the value of a String is based on the characters of the string; the Equals method of the String class returns true for any two string instances that contain exactly the same characters in the same order.

Types that implement IComparable must override Equals.

Types that override Equals must also override GetHashCode; otherwise, Hashtable might not work correctly.

If your programming language supports operator overloading and if you choose to overload the equality operator for a given type, that type must override the Equals method. Such implementations of the Equals method must return the same results as the equality operator. Following this guideline will help ensure that class library code using Equals (such as ArrayList and Hashtable) behaves in a manner that is consistent with the way the equality operator is used by application code.

The following guidelines are for implementing a value type:

*

  Consider overriding Equals to gain increased performance over that provided by the default implementation of Equals on ValueType.
*

  If you override Equals and the language supports operator overloading, you must overload the equality operator for your value type.

The following guidelines are for implementing a reference type:

*

  Consider overriding Equals on a reference type if the semantics of the type are based on the fact that the type represents some value(s).
*

  Most reference types must not overload the equality operator, even if they override Equals. However, if you are implementing a reference type that is intended to have value semantics, such as a complex number type, you must override the equality operator

using System; class Program { static void Main(string[] args) { Object Obj1 = new Object(); Object Obj2 = new Object(); Console.WriteLine(Obj1.Equals(Obj2)); Obj2 = Obj1; Console.WriteLine(Obj1.Equals(Obj2)); } }

lavi
Could you please format this better? Make your lists into lists and code into lists et cetera...
Svish