c# - Immediate Window and runtime giving different results for same LINQ statement -
i have piece of code compares 2 collections, , returns items 1 list doesn't belong in other.
as these 2 lists contain objects aren't equitable reference, have simple iequatable
compares objects on ids.
the code running follows:
private preferencedefinition[] finduserpreferencestoadd(preferencedefinition[] newdefinitions, preferencedefinition[] olddefinitions) { //get newly selected definitions var newpreferences = newdefinitions.where(def => def.isselected); //get new definitions don't exist in old list var preferencestoadd = newpreferences.where(def => !olddefinitions.contains(def)).toarray(); return preferencestoadd; }
the result of preferencestoadd
gives me exact same list in newpreferences
, despite purposely ensuring newdefinitions
contains additional item has been selected. if pass in 7 new preferences, return 7 preferences 'add' - incorrect implementation.
however, when run exact same linq statement in immediate window when hit breakpoint on return, gives me:
newpreferences.where(def => !olddefinitions.contains(def)).toarray(); {app1test.preferencedefinition[1]} [0]: {app1test.preferencedefinition}
this contains single result should added.
why immediate window give me correct result, run time code wouldn't? tried running statement in immediate window before , after runtime linq query ran ensure wasn't order of operations thing, made no difference.
edit:
i have found solution issue, replacing second linq statement with:
var preferencestoadd = newpreferences.where(d => !olddefinitions.any(def => def.equals(d))).toarray();
however don't understand why original did not work. have similar scenario opposite of i'm trying achieve here (find items delete), , works fine. missing something?
edit 2:
this code, without iequatable, worked fine:
private preferencedefinition[] finduserpreferencestodelete(preferencedefinition[] newdefinitions, preferencedefinition[] olddefinitions) { //get newly selected definitions var newpreferences = newdefinitions.where(def => def.isselected); //get old definitions don't exist in new list var preferencestodelete = olddefinitions.where(def => !newpreferences.contains(def)); return preferencestodelete.toarray(); }
why work fine, first method wouldn't?
have here:
https://msdn.microsoft.com/en-us/library/ms131187(v=vs.110).aspx
if implement iequatable, should override base class implementations of object.equals(object) , gethashcode behavior consistent of iequatable.equals method.
you can deduct == operator not affected implementing iequatable;
therefore equals call uses custom equality method , contains internally use object.equals not overridden.
the array implements icollection therefore contains method used internally implemented in array indexof without using equalitycomparer.default tries use iequatable.equals if any.
try adding this:
public override bool equals(object obj) { var test = obj test; return test == null ? obj.equals(this) : equals(test); }
you can see simple example here: https://dotnetfiddle.net/c5r4be
Comments
Post a Comment