terribly useful:
Object o = new object();
The System.Object
class exposes four instance methods (see Figure 4-5):
□ Equals()
— Checks whether the value of the current object is equal to that of another object. By default, the Equals()
method checks for
□ GetHashCode()
— Returns a hash code for the class. The GetHashCode ()
method is suitable for use in hashing algorithms and data structures, such as a hash table. There will be more about hashing in Chapter 11
□ GetType()
— Returns the type of the current object
□ ToString()
— Returns the string representation of an object

Figure 4-5
In addition, the System.Object
class also has two static methods (see Figure 4-6):
□ Equals()
— Returns true if the two objects are equal (see next section for more details)
□ ReferenceEquals()
— Returns true if two objects are from the same instance

Figure 4-6
All classes that inherit from System.Object
also inherit all the four instance methods, a couple of which you will learn in more details in the following sections.
Testing for Equality
Consider the following three instances of the Contact
class, which implicitly inherits from the System.Object
class:
Contact c1 = new Contact() {
ID = 1234,
FirstName = 'Wei-Meng',
LastName = 'Lee',
Email = '[email protected]'
};
Contact c2 = new Contact() {
ID = 1234,
FirstName = 'Wei-Meng',
LastName = 'Lee',
Email = '[email protected]'
};
Contact c3 = new Contact() {
ID = 4321,
FirstName = 'Lee',
LastName = 'Wei-Meng',
Email = '[email protected]'
};
As you can see, c1
and c2
are identical in data member values, while c3
is different. Now, let's use the following statements to see how the Equals()
and ReferenceEquals()
methods work:
Console.WriteLine(c1.Equals(c2)); //---False---
Console.WriteLine(c1.Equals(c3)); //---False---
c3 = c1;
Console.WriteLine(c1.Equals(c3)); //---True---
Console.WriteLine(Object.ReferenceEquals(c1, c2)); //---False---
Console.WriteLine(Object.ReferenceEquals(c1, c3)); //---True---
The first statement might be a little surprising to you; did I not just mention that you can use the Equals()
method to test for value equality?
Console.WriteLine(c1.Equals(c2)); //---False---
In this case, c1
and c2
have the exact same values for the members, so why does the Equals()
method return False
in this case? It turns out that the Equals()
method must be overridden in the Contact
class definition. This is because by itself, the System.Object
class does not know how to test for the equality of your custom class; the Equals()
method is a virtual method and needs to be overridden in derived classes. By default, the Equals()
method tests for reference equality.
The second statement is straightforward, as c1
and c3
are two different objects:
Console.WriteLine(c1.Equals(c3)); //---False---
The third and fourth statements assign c1
to c3
, which means that c1
and c3
are now two different variables pointing to the same object. Hence, Equals()
returns True
:
c3 = c1;
Console.WriteLine(c1.Equals(c3)); //---True---
The fifth and sixth statements test the reference equality of c1
against c2
and then c1
against c3
:
Console.WriteLine(Object.ReferenceEquals(c1, c2)); //---False---
Console.WriteLine(Object.ReferenceEquals(c1, c3)); //---True---
If two objects have reference equality, they also have value equality, but the reverse is not necessarily true.
Implementing Equals
By default the Equals()
method tests for reference equality. To ensure that it tests for value equality rather than reference equality, you need to override the Equals()
virtual method.
Using the same Contact
class used in the previous section, add the methods highlighted in the following code:
public class Contact {
public int ID;
public string FirstName;
public string LastName;
public string Email;