1

我有这个,但它太短了,我几乎可以肯定我错过了一些东西:

public static bool ValueEquals<TKey, TValue>
    (this IDictionary<TKey, TValue> source, IDictionary<TKey, TValue> toCheck)
{
    if (object.ReferenceEquals(source, toCheck))
        return true;
    if (source == null || toCheck == null || source.Count != toCheck.Count)
        return false;
    return source.OrderBy(t => t.Key).SequenceEqual(toCheck.OrderBy(t => t.Key));
}

因此,基本上,如果它们具有相同的引用,则 return true。如果它们中的任何一个是null或它们的计数不同,则返回false。如果序列(按键排序,然后按值排序)相同,则返回。我一定错过了什么,因为它太短了,不够好。

4

1 回答 1

4

是的,只要键都实现IComparable并且键和值都有一个Equals方法来比较您希望它比较的内容,您的代码就可以工作。如果键或值没有这些方法的适当实现,那么这将不起作用。

您的方法也没有为要传入的自定义IComparerIEqualityComparer对象提供功能,以解决对象没有这些方法之一的理想实现的情况。在您的特定情况下这是否是一个问题,我们不能说。

您的解决方案还需要对所有值进行排序,这比 set equals 的其他可能实现的效率要低一些,但它并没有明显更糟,所以如果您没有特别大的集合,这不应该是一个大问题。

具有与您的功能相当但速度提高的方法是(保留您拥有的前两项检查):

return !source.Except(toCheck).Any();

由于这种方法不依赖于排序,它还提供了不需要TKey实现的好处IComparable

此方法和您的方法都有效的一个关键原因是,它KeyValuePair覆盖了它的定义EqualsGetHashCode基于它自己的引用,而是基于它包装的键和值。如果键和值都相等,则两个KeyValuePairs相等,并且哈希码包含键和值的哈希码。

于 2013-06-05T16:23:29.720 回答