如何比较键值对的相等性?

3
我有两个 KeyValuePair<string, object> 数组。 我正在比较这两个数组,但注意到当 KeyValuePair 的值是转换为对象的值类型时,例如 object{int},具有相同键和值的对将不被认为相等。 但是,当引用类型强制转换为值类型时,例如 object{string},具有相同键和值的两个对将被视为相等。
我在对两个数组使用 .Except() 方法时发现了这个问题,并注意到尽管它们是相同的,但只有具有字符串值的对被集合差异所移除。 从我对 KeyValuePair 的相等比较器进行研究所见,相等是按值而不是按引用进行比较的。 有趣的是,具有字符串值的对的引用应该是不同的。
// 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 最终成为了 array1 中所有非字符串值的一对,尽管 array1 中的所有键和值与 array2 中的一对完全相同。

编辑:下面是调试器中报告的 array1array2 的值:

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

Prop2 拥有的键其值类型为 object{string},而其他键值对的值类型为 object{int}

所有属于 Prop1Prop3 的键值对仍然存在于集合中,而所有属于 Prop2 的键值对已被移除。


一个示例,包含出现错误的数据数组,会很有帮助。 - undefined
@Magnus刚刚添加了失败的数据 - undefined
调试器视图并没有告诉我们更多信息。这里的A是什么?这里的1是什么?而且,真正重要的是以什么内容开始的。 - undefined
1
我用两个相等的数组进行了测试,包含new KeyValuePair<string, object>[] { new KeyValuePair<string, object>("Prop1", 1), new KeyValuePair<string, object>("Prop2", "A"), new KeyValuePair<string, object>("Prop2", "B"), new KeyValuePair<string, object>("Prop3", 3), new KeyValuePair<string, object>("Prop1", 2), };,结果如预期,我得到了空结果。 - undefined
1
KeyValuePair没有重写Equals()方法。当你将其强制转换为(object)进行装箱时,你会得到Object.Equals()。由于它比较的是对象的身份,所以对于两个装箱的值来说,它永远不会为真。 - undefined
可能是为什么KeyValuePair不重写Equals()和GetHashCode()?的重复问题。 - undefined
1个回答

1

KeyValuePair 使用默认方法进行结构相等性比较。如果两个 KeyValuePair<TKey, TValue>Key 属性在其类型的默认相等性比较下相等,并且 Value 属性在其类型的默认相等性比较下相等,则它们相等。否则,它们不相等。

我没有找到你所报告的情况。例如:

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

返回一个空序列,因为这两个数组的内容是相同的。

我想知道您是否有一些成对的值是某种引用类型,而该类型不会覆盖Equals()方法,因此仅当它们是相同对象时才被认为是相等的。换句话说,kvp1.Value.Equals(kvp2.Value)将返回false。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接