我正在尝试使用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。情况似乎并非如此。
有人可以解释为什么以及如何让这种行为发挥作用?
答案 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)
您将新对象(数组或列表)作为键传递。作为新对象,它具有不同的引用,因此它被接受为新密钥。