如何缓存具有多个属性的对象

时间:2013-03-14 22:19:58

标签: c# caching dictionary

我正在寻找缓存其唯一性由该对象中所有属性的组合决定的对象。 我拥有的对象是这样的:

    public double A { get; set; }
    public double B { get; set; }
    public short C { get; set; }
    public bool D { get; set; }
    public double E { get; set; }
    public double F { get; set; }
    public double G { get; set; }
    public double H { get; set; }
    public double J { get; set; }
    public double K { get; set; }
    public double[] L { get; set; }
    public double[] M { get; set; }

我可以覆盖GetHashCode并执行return A ^ B ^ C etc...之类的操作 但是,我担心我会发生很多碰撞。

缓存像这样的对象的最佳方法是什么?

2 个答案:

答案 0 :(得分:4)

您可以使用此GetHashCode

public override int GetHashCode()
{
    int hash = 23;
    unchecked
    {
        hash *= 17 + A.GetHashCode();
        hash *= 17 + B.GetHashCode();
        hash *= 17 + C.GetHashCode();
        // the same applies with the rest of your properties ...
        // collections must be treated differently:
        if(L != null)
        {
            hash *= 17 + L.Length;
            foreach(var d in L)
                hash *= 17 + d.GetHashCode();
        }
        if (M != null)
        {
            hash *= 17 + M.Length;
            foreach (var d in M)
                hash *= 17 + d.GetHashCode();
        }         
    }
    return hash;
}

当不同的属性具有相同的值时,这会生成不同的哈希码。如果我省略了素数乘数,那么A==AA==B就不会产生影响。素数用于减少错误碰撞的可能性。

它还会考虑数组及其值+顺序。

这是关于此主题的“必读”:E. Lippert, Guidelines and rules for GetHashCode

答案 1 :(得分:0)

一个简单的(可能不是最佳的)解决方案可能是:

  1. 生成班级的字​​符串表示形式。如果您只有escalar属性,则可以执行类似string.Format("{0}-{1}-{2}", A, B, C)的操作;因为你有数组,所以最好使用StringBuilder并在循环中组合字符串。

  2. 在生成的字符串上调用GetHashCode