数组comprasion作为C#中的Dictionary键

我想创建表示n维数组的类,但是在哪里是对其元素的可交换访问。 例如: a[new[] {4, 7, 55}] == a[new[] {55, 4, 7}]

我编写这段代码,我实现接口IEqualityComparer,以便比较键(它们是数组)的真实内容,但不是refs。

 using System; using System.Collections.Generic; using System.Linq; class NArray { public int this[int[] x] { get { Array.Sort(x); return array[x]; } set { Array.Sort(x); array[x] = value; } } public void Remove(int[] x) { Array.Sort(x); array.Remove(x); } Dictionary array = new Dictionary(new ArrCmpr()); } class ArrCmpr : IEqualityComparer { public bool Equals(int[] a, int[] b) { return a.Length == b.Length && Enumerable.Range(0, a.Length).All(i => a[i] == b[i]); } public int GetHashCode(int[] a) { return a.GetHashCode(); } } 

但是当我开始使用这个类时,我遇到了一个exception:“System.Collections.Generic.KeyNotFoundException:字典中没有给定的键。” 当我尝试将元素输出到控制台时,下两种情况都会发生此exception:

 NArray a = new NArray(); a[new[] { 1, 3, 2 }] = 4; 

Console.WriteLine(a [new [] {3,2,1}]); //错误

 NArray b = new NArray(); b[new[] { 1, 2, 3 }] = 4; Console.WriteLine(b[new[] { 1, 2, 3 }]); //error 

那么问题的原因是什么?我该如何解决?

这是因为你的GetHashCode实现是不正确的:两个不同的数组具有相同顺序的相同项通常不会有相同的哈希码(因为不考虑这些值),所以从不调用Equals

您需要一个GetHashCode实现,它将数组中的值考虑在内:

 class ArrCmpr : IEqualityComparer { public bool Equals(int[] a, int[] b) { return a.SequenceEqual(b); } public int GetHashCode(int[] a) { return a.Aggregate(0, (acc, i) => unchecked(acc * 457 + i * 389)); } } 

对我来说似乎必须更改GetHashCode,因为它只返回Array对象的哈希码,考虑到每次使用NEW哈希码都会有所不同,即使内容相等。

由于您使用Dictionary来存储数组,因此您需要检查密钥是否已存在,然后才能使用[]运算符访问它,否则如果您尝试访问不存在的密钥,则exception是抛出

 // your get function if(array.ContainsKey(x)) return array[x]; else // do something like return null return null; // your set function if(array.ContainsKey(x)) array[x] = value; else array.Add(x, value);