为什么不列出<T> .GetHashCode和ObservableCollection <T> .GetHashCode评估他们的项目?

sjo*_*urg 1 c# hashcode

我认为这些集合的GetHashCode函数不会将其哈希码基于其列表中的项目,这很奇怪.

我需要这个才能提供脏检查(你有未保存的数据).我编写了一个覆盖GetHashCode方法的包装类,但我发现这不是默认实现,这很奇怪.

我想这是性能优化?

class Program
{
    static void Main(string[] args)
    {
        var x = new ObservableCollection<test>();
        int hash = x.GetHashCode();
        x.Add(new test("name"));
        int hash2 = x.GetHashCode();

        var z = new List<test>();
        int hash3 = z.GetHashCode();
        z.Add(new test("tets"));
        int hash4 = z.GetHashCode();

        var my = new CustomObservableCollection<test>();
        int hash5 = my.GetHashCode();
        var test = new test("name");
        my.Add(test);
        int hash6 = my.GetHashCode();
        test.Name = "name2";
        int hash7 = my.GetHashCode();
    }
}

public class test
{
    public test(string name)
    {
        Name = name;
    }

    public string Name { get; set; }

    public override bool Equals(object obj)
    {
        if (obj is test)
        {
            var o = (test) obj;
            return o.Name == this.Name;
        }
        return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return Name.GetHashCode();
    }
}

public class CustomObservableCollection<T> : ObservableCollection<T>
{
    public override int GetHashCode()
    {
        int collectionHash = base.GetHashCode();

        foreach (var item in Items)
        {
            var itemHash = item.GetHashCode();
            if (int.MaxValue - itemHash > collectionHash)
            {
                collectionHash = collectionHash * -1;
            }
            collectionHash += itemHash;
        }
        return collectionHash;
    }
}
Run Code Online (Sandbox Code Playgroud)

dca*_*tro 5

如果确实如此,它将打破一些实施准则GetHashCode.即:

GetHashCode返回的整数永远不会改变

由于列表的内容可以改变,因此其哈希码也将改变.

GetHashCode的实现必须非常快

根据列表的大小,您可能会降低其哈希码的计算速度.

另外,我不相信您应该使用对象的哈希码来检查数据是否脏.碰撞的概率比你想象的要高.