虽然没有像这样的现成集合,但您可以使用 aDictionary<int[],double>
和 custom轻松模拟它们IEqualityComparerer<int[]>
,如下所示:
class ArrayEq : IEqualityComparerer<int[]> {
public bool Equals(int[] a, int[] b) {
return a.SequenceEquals(b);
}
public int GetHashCode(int[] a) {
return a.Aggregate(0, (p, v) => 31*p + v);
}
}
有了这个相等比较器,您可以这样做:
// The number of dimensions does not matter: if you pass a different number
// of dimensions, nothing bad is going to happen.
IDictionary<int[],double> array = new Dictionary<int[],double>(new ArrayEq());
array[new[] {1,2,3}] = 4.567;
array[new[] {1,2,-3}] = 7.654; // Negative indexes are OK
double x = array[new[] {1,2,3}]; // Get 4.567 back
如果您需要有一定的容量和特定数量的维度,您可以修改ArrayEq
以更严格地验证数据。
如果您在编译时知道维数,则可以使用其中一个Tuple<...>
类而不是数组来获得更好的性能。您还可以在多维数组上定义扩展方法,例如double[,,,]
,数组,以获取索引向量。但是,这两种方法都没有提供相同的灵活性(这是一种常见的权衡——通常可以通过降低灵活性来获得更好的性能)。
编辑:如果您需要预先分配存储空间并避免存储索引,您可以自己实现一个多维数组 - 如下所示:
class MultiD<T> {
private readonly T[] data;
private readonly int[] mul;
public MultiD(int[] dim) {
// Add some validation here:
// - Make sure dim has at least one dimension
// - Make sure that all dim's elements are positive
var size = dim.Aggregate(1, (p, v) => p * v);
data = new T[size];
mul = new int[dim.Length];
mul[0] = 1;
for (int i = 1; i < mul.Length; i++) {
mul[i] = mul[i - 1] * dim[i - 1];
}
}
private int GetIndex(IEnumerable<int> ind) {
return ind.Zip(mul, (a, b) => a*b).Sum();
}
public T this[int[] index] {
get { return data[GetIndex(index)]; }
set { data[GetIndex(index)] = value; }
}
}
这是使用泛型的行主要索引方案的直接实现。