5

这是为两个字典的相等性创建比较器的最佳方法吗?这需要准确。请注意, Entity.Columns 是 KeyValuePair(string, object) 的字典:

public class EntityColumnCompare : IEqualityComparer<Entity>
{
    public bool Equals(Entity a, Entity b)
    {
        var aCol = a.Columns.OrderBy(KeyValuePair => KeyValuePair.Key);
        var bCol = b.Columns.OrderBy(KeyValuePAir => KeyValuePAir.Key); 

        if (aCol.SequenceEqual(bCol))
            return true;
        else
            return false;           
    }

    public int GetHashCode(Entity obj)
    {
        return obj.Columns.GetHashCode(); 
    }
}

也不太确定 GetHashCode 的实现。

谢谢!

4

3 回答 3

8

这是我要做的:

    public bool Equals(Entity a, Entity b)
    {
        if (a.Columns.Count != b.Columns.Count)
            return false; // Different number of items

        foreach(var kvp in a.Columns)
        {
            object bValue;
            if (!b.Columns.TryGetValue(kvp.Key, out bValue))
                return false; // key missing in b
            if (!Equals(kvp.Value, bValue))
                return false; // value is different
        }
        return true;
    }

这样您就不需要对条目进行排序(这是一个O(n log n)操作):您只需要枚举第一个字典(O(n))中的条目并尝试通过键检索值第二个字典(O(1)),所以整体复杂度是O(n)

另外,请注意您的GetHashCode方法不正确:在大多数情况下,即使它们具有相同的内容,它也会为不同的字典实例返回不同的值。如果哈希码不同,Equals则永远不会被调用...您有几个选项可以正确实现它,但都不理想:

  • 从字典的内容构建哈希码:将是最好的选择,但它很慢,GetHashCode需要快速
  • 总是返回相同的值,这样Equals总是会被调用:如果你想在哈希表/字典/哈希集中使用这个比较器,那就太糟糕了,因为所有实例都将落在同一个桶中,导致O(n)访问而不是O (1)
  • 返回Count字典的值(如 digEmAll 所建议的那样):它不会给出很好的分布,但仍然比总是返回相同的值要好,并且它满足约束GetHashCode(即被认为相等的对象应该具有相同的哈希码;两个“相等”的字典具有相同数量的项目,所以它有效)
于 2011-03-23T21:25:18.427 回答
2

想到这样的事情,但可能会有更有效的事情:

public static bool Equals<TKey, TValue>(IDictionary<TKey, TValue> x, 
    IDictionary<TKey, TValue> y)
{
    return x.Keys.Intersect(y.Keys).Count == x.Keys.Count &&
        x.Keys.All(key => Object.Equals(x[key], y[key]));
}
于 2011-03-23T21:23:32.610 回答
1

这对我来说似乎很好,也许不是最快的,但很有效。

您只需要更改GetHashCode错误的实现即可。

例如你可以返回obj.Columns.Count.GetHashCode()

于 2011-03-23T21:25:16.617 回答