创建一个只指向另一个数组的一部分的数组?

我有一个包含引用类型元素的巨大数组,我想创建许多其他数组,这些数组基本上只指向那个大数组的特定部分。

换句话说,我想创建“索引器”或“长度指针”。

在C ++中,使用指针很容易,并为每个指针分配一个长度,例如创建一个包含长度指针的结构。

我怎样才能在C#/ .NET中实现这一目标?

重点是避免复制任何东西,我只想指向已经存在于内存中的数组中的特定部分。

有任何想法吗?

Jon建议使用ArraySegment可能就是你想要的。 但是,如果你想要表示一个指向数组内部的指针,那么就可以在C ++中使用,这里有一些代码。 不作任何明示或暗示的保证,使用风险自负。

此代码不以任何方式跟踪内部指针的“长度”,但如果需要,可以很容易地添加该function。

 internal struct ArrayPtr { public static ArrayPtr Null { get { return default(ArrayPtr); } } private readonly T[] source; private readonly int index; private ArrayPtr(ArrayPtr old, int delta) { this.source = old.source; this.index = old.index + delta; Debug.Assert(index >= 0); Debug.Assert(index == 0 || this.source != null && index < this.source.Length); } public ArrayPtr(T[] source) { this.source = source; index = 0; } public bool IsNull() { return this.source == null; } public static bool operator <(ArrayPtr a, ArrayPtr b) { Debug.Assert(Object.ReferenceEquals(a.source, b.source)); return a.index < b.index; } public static bool operator >(ArrayPtr a, ArrayPtr b) { Debug.Assert(Object.ReferenceEquals(a.source, b.source)); return a.index > b.index; } public static bool operator <=(ArrayPtr a, ArrayPtr b) { Debug.Assert(Object.ReferenceEquals(a.source, b.source)); return a.index <= b.index; } public static bool operator >=(ArrayPtr a, ArrayPtr b) { Debug.Assert(Object.ReferenceEquals(a.source, b.source)); return a.index >= b.index; } public static int operator -(ArrayPtr a, ArrayPtr b) { Debug.Assert(Object.ReferenceEquals(a.source, b.source)); return a.index - b.index; } public static ArrayPtr operator +(ArrayPtr a, int count) { return new ArrayPtr(a, +count); } public static ArrayPtr operator -(ArrayPtr a, int count) { return new ArrayPtr(a, -count); } public static ArrayPtr operator ++(ArrayPtr a) { return a + 1; } public static ArrayPtr operator --(ArrayPtr a) { return a - 1; } public static implicit operator ArrayPtr(T[] x) { return new ArrayPtr(x); } public static bool operator ==(ArrayPtr x, ArrayPtr y) { return x.source == y.source && x.index == y.index; } public static bool operator !=(ArrayPtr x, ArrayPtr y) { return !(x == y); } public override bool Equals(object x) { if (x == null) return this.source == null; var ptr = x as ArrayPtr?; if (!ptr.HasValue) return false; return this == ptr.Value; } public override int GetHashCode() { unchecked { int hash = this.source == null ? 0 : this.source.GetHashCode(); return hash + this.index; } } public T this[int index] { get { return source[index + this.index]; } set { source[index + this.index] = value; } } } 

现在我们可以做以下事情:

 double[] arr = new double[10]; var p0 = (ArrayPtr)arr; var p5 = p0 + 5; p5[0] = 123.4; // sets arr[5] to 123.4 var p7 = p0 + 7; int diff = p7 - p5; // 2 

听起来你正在寻找像ArraySegment这样的东西。 与我之前的想法相反,它确实有一个索引器并实现IEnumerable等 – 它只是用显式接口完成的。

示例代码:

 using System; using System.Collections.Generic; static class Test { static void Main() { string[] original = { "The", "quick", "brown", "fox", "jumped", "over", "the", "lazy", "dog" }; IList segment = new ArraySegment(original, 3, 4); Console.WriteLine(segment[2]); // over foreach (var word in segment) { Console.WriteLine(word); // fox jumped over the } } } 

编辑:正如评论中所指出的, ArraySegment在.NET 4.5中只是真正“完全正常”。 .NET 4版本不实现任何接口。

您可以使用LINQ:

 yourArray.Skip(startIndex).Take(numberToTake) 

该查询被懒惰地评估。