Monday, 15 August 2011

c# - IEnumerable.GroupBy not grouping -



c# - IEnumerable.GroupBy not grouping -

i having problem using of groupby extension in .net (4.5, no matter if vb.net or c#. exaples in c#). here situation:

2 illustration classes:

public class office : iequatable<office> { public string name { get; set; } public int id { get; set; } public string stuff { get; set; } // compare values public bool equals(object obj) { if (obj office) { office cmp = (office) obj; bool result = true; result &= cmp.id == this.id; result &= cmp.name == this.name; result &= cmp.stuff == this.stuff; homecoming result; } else homecoming false; } // hashcode values public int gethashcode() { var obj = new { id = this.id, name = this.name, stuff = this.stuff }; homecoming obj.gethashcode(); } // iequatable uses overriden equals implementation bool iequatable<office>.equals(office other) { homecoming this.equals(other); } } public class company { public office office { get; set; } public string name { get; set; } }

class office has overriden equality comparing functions , implements iequatable interface, in case (as understand) default equalitycomparer uses impementation of equals.

now want grouping list of companies according offices occupy, this:

list<company> companies = new list<company>(); office office1 = new office(); office1.id = 1; office1.name = "office"; office1.stuff = "stuff"; office office2 = new office(); office2.id = 1; office2.name = "office"; office2.stuff = "stuff"; company date1 = new company(); date1.office = office1; date1.name = "date 1"; company date2 = new company(); date2.office = office2; date2.name = "date 2"; companies.add(date1); companies.add(date2); ienumerable<igrouping<office, company>> grouping = companies.groupby(x => x.office); console.writeline("groups: " + grouping.count()); // returns 2!!! console.writeline("equals: " + office1.equals(office2)); // returns true console.writeline("hash 1: " + office1.gethashcode()); // returns 2067935290 console.writeline("hash 2: " + office2.gethashcode()); // returns 2067935290 iequalitycomparer cmp = equalitycomparer<office>.default; console.writeline("comparer: " + cmp.equals(office1, office2)); // returns true

you can see each company has different office object, in logic of application these objects considered equal. hence calling office1.equals(office2) returns true, object hashcodes equal , using equalitycomparer<office>.default's function equals returns true.

now mystery why calling groupby office returns 2 groups, though offices "equal". documentation states key's default equalitycomparer used (http://msdn.microsoft.com/en-us/library/vstudio/bb534501(v=vs.100).aspx).

thanks help~

the default comparer calling object.gethashcode , iequatable<office>.equals.

this isn't working because hiding gethashcode() member, not overriding it.

your equals , gethashcode methods should changed:

public **override** bool equals(object obj) public **override** int gethashcode()

c# .net vb.net equality

No comments:

Post a Comment