c# - Intersect with a custom IEqualityComparer using Linq -
long story short: have 2 collections of objects. 1 contains values (let's call "good"), other default values (mr. "default"). want intersect of union between , default, , default. in other words: intersect(union(good, default), default). 1 might think resolves default, here gets tricky : use custom iequalitycomparer.
i got following classes :
class myclass { public string mystring1; public string mystring2; public string mystring3; } class myequalitycomparer : iequalitycomparer<myclass> { public bool equals(myclass item1, myclass item2) { if(item1 == null && item2 == null) return true; else if((item1 != null && item2 == null) || (item1 == null && item2 != null)) return false; return item1.mystring1.equals(item2.mystring1) && item1.mystring2.equals(item2.mystring2); } public int gethashcode(myclass item) { return new { item.mystring1, item.mystring2 }.gethashcode(); } } here characteristic of collections , default collections :
default : it's large set, containing wanted { mystring1, mystring2 } pairs, mystring3 values are, can guess, default values.
good : it's smaller set, containing items in default set, mystring3 values. has { mystring1, mystring2 } outside of wanted set.
what want : take items in default, add other items in default that.
here is, think is, best try :
halfwantedresult = good.union(default, new myequalitycomparer()); wantedresult= halfwantedresult.intersect(good, new myequalitycomparer()); i taught should have worked, result { mystring1, mystring2 } pairs set, coming default set, have default value across. tried switching default , of last intersect, same result.
first of wrong:
public bool equals(myclass item1, myclass item2) { return gethashcode(item1) == gethashcode(item2); } if hashcode's different sure corresponding 2 items different, if they're equal not guaranteed corresponding 2 items equal.
so correct equals implementation:
public bool equals(myclass item1, myclass item2) { if(object.referenceequals(item1, item2)) return true; if(item1 == null || item2 == null) return false; return item1.mystring1.equals(item2.mystring1) && item1.mystring2.equals(item2.mystring2); } as slacks suggested (anticipating me) code following:
var default = new list<myclass> { new myclass{mystring1="a",mystring2="a",mystring3="-"}, new myclass{mystring1="b",mystring2="b",mystring3="-"}, new myclass{mystring1="x",mystring2="x",mystring3="-"}, new myclass{mystring1="y",mystring2="y",mystring3="-"}, new myclass{mystring1="z",mystring2="z",mystring3="-"}, }; var = new list<myclass> { new myclass{mystring1="a",mystring2="a",mystring3="+"}, new myclass{mystring1="b",mystring2="b",mystring3="+"}, new myclass{mystring1="c",mystring2="c",mystring3="+"}, new myclass{mystring1="d",mystring2="d",mystring3="+"}, new myclass{mystring1="e",mystring2="e",mystring3="+"}, }; var wantedresult = good.intersect(default, new myequalitycomparer()) .union(default, new myequalitycomparer()); // wantedresult: // a + // b b + // x x - // y y - // z z -
Comments
Post a Comment