Equals why ? and why not ==

In Object oriented programming languages, there is a nice keyword that is “new” what this does is create a new instance of a object and run the objects constructor method and setup up the internal variables, for example.

class classA 
{
	private int x;
 	public	classA() { x= 0;}
	public	classA(int value) { x = value;}
}
...
classA a = new classA();

this will create a new instance of A with the constructor (same name as the class) setting x equal to 0. What is happening is that the variable “a” is pointing to a memory location of the newly created object on the memory heap for example.

Local variables

Object Memory location / value
a 0x0102

which the 0x0102 memory location is pointing to a newly constructed classA space

Memory location Object values
0x0102 classA – a instance over head (garage collection etc)
0x0104 x value 0

There is over head details associated with the classA (a instance) for the garage collection/polymorphism for example. So the actual “a” variable is just pointing to this place in memory, if you created a new classA instance then another place in memory will be created, for example lets create classA a2 as

classA a2 = new classA();

and now a example of the memory locations / values would be similar to

Local variables

Object Memory location / value
a 0x0102
a2 0x0108

with the memory heap as such.

Memory location Object values
0x0102 classA – a instance over head (garage collection etc)
0x0104 x value 0
0x0108 classA – a2 instance over head (garage collection etc)
0x010a x value 0

so you would have thought that if you did,

if (a == a2)

then they would be equal, since both have a value of 0 ? well this is not the case, since the == is just comparing the value within the variable and thus the a = 0x0102 and a2 = 0x0108 which are not equal. To compare two different instances of a class you need to override the Equals function within the class (all classes are derived from object class)

So the code would be

		// override the inhertant object object Equals function
		public override bool Equals(object obj)
		{
			// cast the obj into a classA and then compare the x values
			if (x == ((classA)obj).x)
				return true;
			else
				return false;
		}

and now you can compare the two classA instances with

if (a.Equals(a2))

since the Equals function is actually comparing the values within the class instance and not the a/a2 variable values (which point to memory locations).

Here is the full code

using System;
 
namespace equaltest
{
	class classA 
	{
		private int x;
	 	public	classA() { x= 0;}
		public	classA(int value) { x = value;}
 
		public int xValue {
			get { return x;}
			set { x = value;}
		}
 
		// override the inhertant object object Equals function
		public override bool Equals(object obj)
		{
			// cast the obj into a classA and then compare the x values
			if (x == ((classA)obj).x)
				return true;
			else
				return false;
		}
	}
 
	class MainClass
	{
		public static void Main(string[] args)
		{
			classA a = new classA();
			a.xValue = 10;
			Console.WriteLine("A x value = " + a.xValue);
 
			classA a2 = new classA();
			a2.xValue = 10;
			Console.WriteLine("A2 x value = " +a2.xValue);
			//so they are the same in x values, but are they the same !! ==
 
			if (a == a2)
				Console.WriteLine("a does equal a2");
			else
				Console.WriteLine("a does not equal a2");
 
			// of course they are NOT the same value, because the equals is comparing there actual object values
			// and not there x value inside them, and with the "new" keyword they are both pointing to different 
			// places on the heap of storage, thus they are NOT the same..
			// a may equal heap storage = 0x1010
			// a2 may equal heap storage= 0x1020
			// both have the same x value but different memory location values.
 
			// but implementing a Eqauls comparsion function you can compare the two variables internals 
			// as you see fit.
			if (a.Equals(a2))
				Console.WriteLine("a does equal a2");
			else
				Console.WriteLine("a does not equal a2");
 
		}
	}
}

and the output would be

A x value = 10
A2 x value = 10
a does not equal a2
a does equal a2

since I am overriding the Equals from the base object class, the compiler may warn that I am not overriding the GetHaseCode(), but that is k for this example.

Example of the compiler warning message

Description=`equaltest.classA' overrides Object.Equals(object) but does not override Object.GetHashCode()(CS0659)]

Leave a Reply

Your email address will not be published. Required fields are marked *