{"id":724,"date":"2010-02-16T11:04:01","date_gmt":"2010-02-16T11:04:01","guid":{"rendered":"http:\/\/www.codingfriends.com\/?p=724"},"modified":"2010-02-16T11:10:11","modified_gmt":"2010-02-16T11:10:11","slug":"equals-why-and-why-not","status":"publish","type":"post","link":"https:\/\/www.codingfriends.com\/index.php\/2010\/02\/16\/equals-why-and-why-not\/","title":{"rendered":"Equals why ? and why not =="},"content":{"rendered":"<p>In Object oriented programming languages, there is a nice keyword that is &#8220;new&#8221; 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.<\/p>\n<pre lang=\"csharp\">\r\nclass classA \r\n{\r\n\tprivate int x;\r\n \tpublic\tclassA() { x= 0;}\r\n\tpublic\tclassA(int value) { x = value;}\r\n}\r\n...\r\nclassA a = new classA();\r\n<\/pre>\n<p>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 &#8220;a&#8221; is pointing to a memory location of the newly created object on the memory heap for example.<\/p>\n<p>Local variables<\/p>\n<table>\n<tr>\n<td style=\"width : 150px;\">Object<\/td>\n<td>Memory location \/ value<\/td>\n<\/tr>\n<tr>\n<td>a<\/td>\n<td>0x0102<\/td>\n<\/tr>\n<\/table>\n<p>which the 0x0102 memory location is pointing to a newly constructed classA space<\/p>\n<table>\n<tr>\n<td style=\"width : 150px;\">Memory location<\/td>\n<td style=\"width : 150px;\">Object<\/td>\n<td>values<\/td>\n<\/tr>\n<tr>\n<td>0x0102<\/td>\n<td>classA &#8211; a instance<\/td>\n<td>over head (garage collection etc)<\/td>\n<\/tr>\n<tr>\n<td>0x0104<\/td>\n<td>x value<\/td>\n<td>0<\/td>\n<\/tr>\n<\/table>\n<p>There is over head details associated with the classA (a instance) for the garage collection\/polymorphism for example.  So the actual &#8220;a&#8221; 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<\/p>\n<pre lang=\"csharp\">\r\nclassA a2 = new classA();\r\n<\/pre>\n<p>and now a example of the memory locations \/ values would be similar to <\/p>\n<p>Local variables<\/p>\n<table>\n<tr>\n<td style=\"width : 150px;\">Object<\/td>\n<td>Memory location \/ value<\/td>\n<\/tr>\n<tr>\n<td>a<\/td>\n<td>0x0102<\/td>\n<\/tr>\n<tr>\n<td>a2<\/td>\n<td>0x0108<\/td>\n<\/tr>\n<\/table>\n<p>with the memory heap as such.<\/p>\n<table>\n<tr>\n<td style=\"width : 150px;\">Memory location<\/td>\n<td style=\"width : 150px;\">Object<\/td>\n<td>values<\/td>\n<\/tr>\n<tr>\n<td>0x0102<\/td>\n<td>classA &#8211; a instance<\/td>\n<td>over head (garage collection etc)<\/td>\n<\/tr>\n<tr>\n<td>0x0104<\/td>\n<td>x value<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<td>0x0108<\/td>\n<td>classA &#8211; a2 instance<\/td>\n<td>over head (garage collection etc)<\/td>\n<\/tr>\n<tr>\n<td>0x010a<\/td>\n<td>x value<\/td>\n<td>0<\/td>\n<\/tr>\n<\/table>\n<p>so you would have thought that if you did, <\/p>\n<pre lang=\"csharp\">\r\nif (a == a2) \r\n<\/pre>\n<p>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)<\/p>\n<p>So the code would be<\/p>\n<pre lang=\"csharp\">\r\n\t\t\/\/ override the inhertant object object Equals function\r\n\t\tpublic override bool Equals(object obj)\r\n\t\t{\r\n\t\t\t\/\/ cast the obj into a classA and then compare the x values\r\n\t\t\tif (x == ((classA)obj).x)\r\n\t\t\t\treturn true;\r\n\t\t\telse\r\n\t\t\t\treturn false;\r\n\t\t}\r\n<\/pre>\n<p>and now you can compare the two classA instances with <\/p>\n<pre lang=\"csharp\">\r\nif (a.Equals(a2))\r\n<\/pre>\n<p>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).<\/p>\n<p>Here is the full code<\/p>\n<pre lang=\"csharp\">\r\nusing System;\r\n\r\nnamespace equaltest\r\n{\r\n\tclass classA \r\n\t{\r\n\t\tprivate int x;\r\n\t \tpublic\tclassA() { x= 0;}\r\n\t\tpublic\tclassA(int value) { x = value;}\r\n\t\t\r\n\t\tpublic int xValue {\r\n\t\t\tget { return x;}\r\n\t\t\tset { x = value;}\r\n\t\t}\r\n\t\t\r\n\t\t\/\/ override the inhertant object object Equals function\r\n\t\tpublic override bool Equals(object obj)\r\n\t\t{\r\n\t\t\t\/\/ cast the obj into a classA and then compare the x values\r\n\t\t\tif (x == ((classA)obj).x)\r\n\t\t\t\treturn true;\r\n\t\t\telse\r\n\t\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\t\r\n\tclass MainClass\r\n\t{\r\n\t\tpublic static void Main(string[] args)\r\n\t\t{\r\n\t\t\tclassA a = new classA();\r\n\t\t\ta.xValue = 10;\r\n\t\t\tConsole.WriteLine(\"A x value = \" + a.xValue);\r\n\t\t\t\r\n\t\t\tclassA a2 = new classA();\r\n\t\t\ta2.xValue = 10;\r\n\t\t\tConsole.WriteLine(\"A2 x value = \" +a2.xValue);\r\n\t\t\t\/\/so they are the same in x values, but are they the same !! ==\r\n\t\t\t\r\n\t\t\tif (a == a2)\r\n\t\t\t\tConsole.WriteLine(\"a does equal a2\");\r\n\t\t\telse\r\n\t\t\t\tConsole.WriteLine(\"a does not equal a2\");\r\n\t\t\t\r\n\t\t\t\/\/ of course they are NOT the same value, because the equals is comparing there actual object values\r\n\t\t\t\/\/ and not there x value inside them, and with the \"new\" keyword they are both pointing to different \r\n\t\t\t\/\/ places on the heap of storage, thus they are NOT the same..\r\n\t\t\t\/\/ a may equal heap storage = 0x1010\r\n\t\t\t\/\/ a2 may equal heap storage= 0x1020\r\n\t\t\t\/\/ both have the same x value but different memory location values.\r\n\t\t\t\r\n\t\t\t\/\/ but implementing a Eqauls comparsion function you can compare the two variables internals \r\n\t\t\t\/\/ as you see fit.\r\n\t\t\tif (a.Equals(a2))\r\n\t\t\t\tConsole.WriteLine(\"a does equal a2\");\r\n\t\t\telse\r\n\t\t\t\tConsole.WriteLine(\"a does not equal a2\");\r\n\t\t\t\r\n\t\t}\r\n\t}\r\n}\r\n<\/pre>\n<p>and the output would be <\/p>\n<pre lang=\"bash\">\r\nA x value = 10\r\nA2 x value = 10\r\na does not equal a2\r\na does equal a2\r\n<\/pre>\n<p>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.<\/p>\n<p>Example of the compiler warning message<\/p>\n<pre lang=\"bash\">\r\nDescription=`equaltest.classA' overrides Object.Equals(object) but does not override Object.GetHashCode()(CS0659)]\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In Object oriented programming languages, there is a nice keyword that is &#8220;new&#8221; 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 = &hellip; <a href=\"https:\/\/www.codingfriends.com\/index.php\/2010\/02\/16\/equals-why-and-why-not\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Equals why ? and why not ==<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[],"class_list":["post-724","post","type-post","status-publish","format-standard","hentry","category-c_sharp"],"_links":{"self":[{"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/posts\/724","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/comments?post=724"}],"version-history":[{"count":9,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/posts\/724\/revisions"}],"predecessor-version":[{"id":734,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/posts\/724\/revisions\/734"}],"wp:attachment":[{"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/media?parent=724"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/categories?post=724"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/tags?post=724"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}