{"id":1380,"date":"2013-02-10T12:32:17","date_gmt":"2013-02-10T11:32:17","guid":{"rendered":"http:\/\/soci.hu\/blog\/?p=1380"},"modified":"2013-02-10T12:32:17","modified_gmt":"2013-02-10T11:32:17","slug":"hashsetadd-vegtelen-ciklus-oka-es-megoldasa","status":"publish","type":"post","link":"https:\/\/soci.hu\/blog\/index.php\/2013\/02\/10\/hashsetadd-vegtelen-ciklus-oka-es-megoldasa\/","title":{"rendered":"HashSet.Add v\u00e9gtelen ciklus oka \u00e9s megold\u00e1sa"},"content":{"rendered":"<p>Alapszab\u00e1ly, hogy HashSet, Dictionary vagy b\u00e1rmi m\u00e1s asszociat\u00edv kollekci\u00f3kban kulcsk\u00e9nt csak immutable objektumokat lehet haszn\u00e1lni. Ennek az az oka, hogy amikor berakunk egy elemet, akkor a kollekci\u00f3 megh\u00edvja az objektumon a GetHashCode-ot, \u00e9s az azonos hashk\u00f3d\u00fa objektumokat list\u00e1ba szervezi. Ha k\u00e9t objektum egyenl\u0151nek tekintend\u0151 (az Equals alapj\u00e1n), akkor a hascodejuknak azonosnak kell lenni. Ha ez nem teljes\u00fcl, vagy id\u0151vari\u00e1ns, azaz k\u00e9s\u0151bb m\u00e1r nem igaz, akkor ezek a kollekci\u00f3k megh\u00fcly\u00fclnek.<br \/>\nA p\u00e9ld\u00e1m \u00edgy n\u00e9zett ki:<\/p>\n<p>public virtual bool Equals(EntityBase other)<br \/>\n\t\t{<br \/>\n\t\t\tif (other == null)<br \/>\n\t\t\t{<br \/>\n\t\t\t\treturn false;<br \/>\n\t\t\t}<br \/>\n\t\t\tif (Id == 0)<br \/>\n\t\t\t{<br \/>\n\t\t\t\t\/\/Transient object<br \/>\n\t\t\t\treturn ReferenceEquals(this, other);<br \/>\n\t\t\t}<br \/>\n\t\t\treturn other.Id == Id;<br \/>\n\t\t}<\/p>\n<p>\t\tpublic override bool Equals(object obj)<br \/>\n\t\t{<br \/>\n            if (!(obj is EntityBase))<br \/>\n            {<br \/>\n                return false;<br \/>\n            }<br \/>\n\t\t\treturn Equals((EntityBase)obj);<br \/>\n\t\t}<\/p>\n<p>\t\tpublic override int GetHashCode()<br \/>\n\t\t{<br \/>\n\t\t\treturn Id;<br \/>\n\t\t}<\/p>\n<p>Eleve l\u00e1tszik, a GetHashCode \u00e9s az Equals nem azonos logika szerint m\u0171k\u00f6dik. A GetHashCode akkor ad vissza azonos hascodeot, ha az idk azonosak. Az Equals viszont az idt\u0151l f\u00fcgg\u0151en vagy az idkat hasonl\u00edtja \u00f6ssze, vagy referenci\u00e1lis kompar\u00e1l\u00e1st csin\u00e1l. Ez m\u00e1r kap\u00e1sb\u00f3l bug.<\/p>\n<p>A m\u00e1sik bug, hogy ez az objektum nem immutable, az Id v\u00e1ltozik, amikor adatb\u00e1zisba besz\u00farjuk az entit\u00e1st, \u00e9s kap egy idt. Emiatt az eg\u00e9sz koncepci\u00f3 beteg.<\/p>\n<p>A HashSet.Add megh\u00edvja a HashSet.AddIfNotPresetet, amiben van egy ciklus:<\/p>\n<p>for (int i = this.m_buckets[num % this.m_buckets.Length] &#8211; 1; i >= 0; i = this.m_slots[i].next)<br \/>\n\t{<br \/>\n\t\tif (this.m_slots[i].hashCode == num &#038;&#038; this.m_comparer.Equals(this.m_slots[i].value, value))<br \/>\n\t\t{<br \/>\n\t\t\treturn false;<br \/>\n\t\t}<br \/>\n\t\tnum3++;<br \/>\n\t}<\/p>\n<p>Ez az ciklus akadt be. Az if felt\u00e9tele sose teljes\u00fclt, \u00edgy sose l\u00e9pett kis a ciklusb\u00f3l, mivel idt kapott az entit\u00e1s, \u00edgy megv\u00e1ltozott az Equals logik\u00e1ja.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Alapszab\u00e1ly, hogy HashSet, Dictionary vagy b\u00e1rmi m\u00e1s asszociat\u00edv kollekci\u00f3kban kulcsk\u00e9nt csak immutable objektumokat lehet haszn\u00e1lni. Ennek az az oka, hogy amikor berakunk&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,4],"tags":[],"class_list":["post-1380","post","type-post","status-publish","format-standard","hentry","category-net","category-szakmai-elet"],"_links":{"self":[{"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1380","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=1380"}],"version-history":[{"count":1,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1380\/revisions"}],"predecessor-version":[{"id":1381,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/posts\/1380\/revisions\/1381"}],"wp:attachment":[{"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=1380"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=1380"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/soci.hu\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=1380"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}