{"id":143,"date":"2008-02-05T01:17:22","date_gmt":"2008-02-05T00:17:22","guid":{"rendered":"http:\/\/people.iola.dk\/arj\/2008\/02\/05\/i-implement-brain-damage\/"},"modified":"2008-03-05T02:03:51","modified_gmt":"2008-03-05T01:03:51","slug":"i-implement-brain-damage","status":"publish","type":"post","link":"https:\/\/people.iola.dk\/arj\/2008\/02\/05\/i-implement-brain-damage\/","title":{"rendered":"Iimplement brain damage"},"content":{"rendered":"<p>Had this annoying bug today where something that seemed perfectly resonable just didn&#8217;t work. After much investigation it appears that once again brain damage from Java has managed to over into C#. The problem is illustrated with the following code (You can ignore the Tuple for now):<\/p>\n<pre class=\"prettyprint\">\r\npublic struct Tuple &lt; TFirst,TSecond &gt;\r\n{\r\n    public TFirst first;\r\n    public TSecond second;\r\n\r\n    public Tuple(TFirst first, TSecond second)\r\n   {\r\n\tthis.first = first;\r\n\tthis.second = second;\r\n   }\r\n}\r\n\r\n[...]\r\n\r\nTuple &lt; int,string &gt; t = new Tuple &lt; int,string &gt;(1, \"1\");\r\nTuple &lt; int,string &gt; t2 = new Tuple &lt; int,string &gt;(2, \"2\");\r\n\r\nList &lt; tuple &lt; int,string &gt; &gt; lt = new List &lt; tuple &lt; int,string &gt; &gt;();\r\nlt.Add(t);\r\nlt.Add(t2);\r\n\r\nList &lt; tuple &lt; int,string &gt; &gt; lt2 = new List &lt; tuple &lt; int,string &gt; &gt;();\r\nlt2.Add(t);\r\nlt2.Add(t2);\r\n\r\nSystem.Console.WriteLine(\"eq {0}, == {1}\", lt.Equals(lt2), lt == lt2);<\/pre>\n<p>Which gives the following result:<\/p>\n<pre class=\"prettyprint\">\r\neq False, == False<\/pre>\n<p>Ok that was strange, in Python and C++ one doesn&#8217;t have to use Equal or anything similar and furthermore == gives the correct result since it compares elements memberwise instead of just checking the reference. I recalled that in Java one has to use Equal on strings, since == just compares references. So I googled around and found an explaination in point in the following link at <a href=\"http:\/\/http:\/\/www.andymcm.com\/csharpfaq.htm\">6.7<\/a>. Note all the special cases. The best part is the following paragraph: &#8220;The implementation of Equals() in System.Object (the one you&#8217;ll inherit by default if you write a class) compares identity, i.e. it&#8217;s the same as operator==&#8221;. Apparently List<t> doesn&#8217;t to that, <a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/ms173147(VS.80).aspx\">despite their efforts to help<\/a>, great&#8230; So we&#8217;ll have to do that ourselves:<\/t><\/p>\n<pre class=\"prettyprint\">\r\npublic static IEnumerable &lt; tuple &lt; T1,T2 &gt; &gt; zip &lt; T1,T2 &gt;\r\n(IEnumerable &lt; T1 &gt; l1, IEnumerable &lt; T2 &gt; l2)\r\n{\r\n   IEnumerator &lt; T1 &gt; i1 = l1.GetEnumerator();\r\n   IEnumerator &lt; T2 &gt; i2 = l2.GetEnumerator();\r\n\r\n   while (i1.MoveNext() &amp;&amp; i2.MoveNext())\r\n       yield return new Tuple &lt; T1,T2 &gt; (i1.Current, i2.Current);\r\n}\r\n\r\npublic static bool sorted_lists_equal &lt; T &gt; (List &lt; T &gt; l1, List &lt; T &gt; l2)\r\nwhere T:IEquatable &lt; T &gt;\r\n{\r\n   if (l1.Count != l2.Count)\r\n       return false;\r\n   foreach (Tuple &lt; T, T &gt; t in zip &lt; T,T &gt;(l1, l2)) {\r\n        if (!t.first.Equals(t.second))\r\n              return false;\r\n         }\r\n   return true;\r\n}<\/pre>\n<p><a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/ms131187.aspx\">IEquatable<t><\/t><\/a> is an interface what basically says that it will compare by value. But even though our Tuple implementation is a struct and thus is a ValueType it doesn&#8217;t implement this interface (the Equals method). It instead automatically defines the == operator to work as one expects since it&#8217;s a ValueType. So we have to change Tuple:<\/p>\n<pre class=\"prettyprint\">\r\npublic struct Tuple &lt; TFirst,TSecond &gt;\r\n: IEquatable &lt; Tuple &lt; TFirst,TSecond &gt; &gt;\r\n{\r\n   public TFirst first;\r\n   public TSecond second;\r\n\r\n   public Tuple(TFirst first, TSecond second)\r\n   {\r\n\tthis.first = first;\r\n\tthis.second = second;\r\n   }\r\n\r\n   public bool Equals(Tuple &lt; TFirst,TSecond &gt; other)\r\n   {\r\n      return first.Equals(other.first) &amp;&amp; second.Equals(other.second);\r\n   }\r\n\r\n    public static bool operator==(Tuple &lt; TFirst,TSecond &gt; lhs,\r\n    Tuple &lt; TFirst,TSecond &gt; rhs)\r\n    {\r\n\treturn lhs.Equals(rhs);\r\n    }\r\n\r\n    public static bool operator!=(Tuple &lt; TFirst,TSecond &gt; lhs,\r\n    Tuple &lt; TFirst,TSecond &gt; rhs)\r\n    {\r\n\treturn !(lhs == rhs);\r\n    }\r\n}<\/pre>\n<p>The last two functions was added because now that we&#8217;re implementing the IEquatable interface the compiler doesn&#8217;t seem to want to implement == and !=.<\/p>\n<p>So instead of the following Python code:<\/p>\n<pre class=\"prettyprint\">\r\na = [(1,\"1\"), (2,\"2\")]\r\nb = [(1,\"1\"), (2,\"2\")]\r\na == b<\/pre>\n<p>We have to do the big mess above :-\/<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Had this annoying bug today where something that seemed perfectly resonable just didn&#8217;t work. After much investigation it appears that once again brain damage from Java has managed to over into C#. The problem is illustrated with the following code (You can ignore the Tuple for now): public struct Tuple &lt; TFirst,TSecond &gt; { public [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27,26,15,19],"tags":[],"class_list":["post-143","post","type-post","status-publish","format-standard","hentry","category-net","category-c","category-iola","category-programming"],"_links":{"self":[{"href":"https:\/\/people.iola.dk\/arj\/wp-json\/wp\/v2\/posts\/143","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/people.iola.dk\/arj\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/people.iola.dk\/arj\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/people.iola.dk\/arj\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/people.iola.dk\/arj\/wp-json\/wp\/v2\/comments?post=143"}],"version-history":[{"count":0,"href":"https:\/\/people.iola.dk\/arj\/wp-json\/wp\/v2\/posts\/143\/revisions"}],"wp:attachment":[{"href":"https:\/\/people.iola.dk\/arj\/wp-json\/wp\/v2\/media?parent=143"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/people.iola.dk\/arj\/wp-json\/wp\/v2\/categories?post=143"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/people.iola.dk\/arj\/wp-json\/wp\/v2\/tags?post=143"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}