如何在C#中使用基元列表或List作为字典的键

时间:2016-04-03 23:39:43

标签: c# dictionary

我正在尝试使用int数组作为C#中的键,我看到的行为是意外的(对我而言)。

var result = new Dictionary<int[], int>();
result[new [] {1, 1}] = 100;
result[new [] {1, 1}] = 200;

Assert.AreEqual(1, result.Count); // false is 2

与List似乎相同。

var result = new Dictionary<List<int>, int>();
result[new List<int> { 1, 1 }] = 100;
result[new List<int> { 1, 1 }] = 200;

Assert.AreEqual(1, result.Count); // false is 2

我希望Dictionary能够使用Equals来判断地图中是否存在Key。情况似乎并非如此。

有人可以解释为什么以及如何让这种行为发挥作用?

3 个答案:

答案 0 :(得分:5)

.NET列表和数组没有内置的相等比较,因此您需要提供自己的:

class ArrayEqComparer : IEqualityComparer<int[]> {

    public static readonly IEqualityComparer<int[]> Instance =
        new ArrayEqComparer();

    public bool Equals(int[] b1, int[] b2) {
        if (b2 == null && b1 == null)
           return true;
        else if (b1 == null | b2 == null)
           return false;
        return b1.SequenceEqual(b2);
    }

    public int GetHashCode(int[] a) {
        return a.Aggregate(37, (p, v) => 31*v + p);
    }
}

现在您可以按如下方式构建字典:

var result = new Dictionary<int[],int>(ArrayEqComparer.Instance);

答案 1 :(得分:1)

Dictionary类允许自定义相等比较器作为字典比较器。实现IEqualityComparer&gt;通过使用Linq.Enumerable.SequenceEquals返回所有列表元素的xor(^运算符)(0 ^ first ^ second ...)和Equals(IList x,IList y)来提供GetHashCode(IList obj)。然后将其实例传递给Dictionary构造函数。

答案 2 :(得分:0)

您将对象(数组或列表)作为键传递。作为对象,它具有不同的引用,因此它被接受为新密钥。