Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are KeyValuePairs compared for equality?

I have two arrays of KeyValuePair<string, object>. I am comparing the two arrays, but noticed that when the value of the KeyValuePair is a value type cast to an object, like object{int}, two pairs with identical keys and value values are not considered equal. However, when a reference type is cast to a value, like object{string}, two pairs with identical key and value values are considered equal.

I discovered this problem when I was using the .Except() method on the two arrays, and noticed although they were identical only the pairs with string values were removed by the set difference. From what I've seen doing research on the equality comparer for KeyValuePair, equality is by value, and not by reference. Curiously, the reference for the pairs with string values should be different anyways.

// array1 and array2 contain the same keys with identical values here

var array1 = GetOldItems(); // This returns a KeyValuePair<string, object>[]
var array2 = GetNewItems(); // This returns a KeyValuePair<string, object>[]
var diff = array1.Except(array2); // The difference is all pairs with non-string value

diff ends up being all pairs in array1 with a non-string value, even though all pairs in array1 had identical keys and values to the pairs in array2.

EDIT: Here is the value of array1 and array2 as reported in the debugger:

{System.Collections.Generic.KeyValuePair<string, object>[5]}
[0]: {[Prop1, 1]}
[1]: {[Prop2, A]}
[2]: {[Prop2, B]}
[3]: {[Prop3, 3]}
[4]: {[Prop1, 2]}

Prop2 has keys where type of value is object{string} and the other pairs have values with type of object{int}.

All pairs for Prop1 and Prop3 remain in the set difference, while all pairs with Prop2 have been removed.

like image 245
pavuxun Avatar asked Dec 07 '25 05:12

pavuxun


1 Answers

KeyValuePair uses the default approach to struct equality. If two KeyValuePair<TKey, TValue> have Key properties that compare as equal for their type's default equality and Value properties that compare as equal for their type's default equality, then they are equal. Otherwise they are not.

I do not find what you report. E.g.:

new[] { new KeyValuePair<string, object>("a", 2) }.Except(
  new[] { (new KeyValuePair<string, object>("a", 2))})

returns an empty sequence, because the contents of the two arrays are identical.

I would wonder if perhaps you have pairs where the values are some reference type that does not override Equals() and so are only considered equal if they are the same object. In other words, that kvp1.Value.Equals(kvp2.Value) would return false.

like image 149
Jon Hanna Avatar answered Dec 08 '25 19:12

Jon Hanna



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!