如何从C#中的现有数组中获取子数组而不进行复制?

时间:2015-06-01 10:20:47

标签: c# arrays

我的问题类似于Getting a sub-array from an existing array,虽然在我的情况下,一点点不同的概念非常重要 - 我无法使用记忆复制。

我们说我有10000个元素的数组X,我需要数组Y,其中包含X中的9000个元素,从X开始#& 39; s指数500.

但我不想将X的一部分复制到新数组Y,因此我不想使用Array.Copy,Array.Clone,System.Block .Copy,IEnumerables等。我希望Y引用X - Y[0]实际上是X[500]Y[1]对应X[501],...,{ {1}}是Y[9000]

因此,例如,X[9500]的更改值将同时更改X[100]的值。我怎样才能在C#中实现这个目标?

3 个答案:

答案 0 :(得分:7)

你可以将它包装在另一个对象中,如下所示:

class View<T>
{
     private T[] _array;
     private long _start;
     private long _length;
     public View(T[] array, long start, long length) { ... }
     public T this[long index] 
     {
         get 
         {
             if (/*do bounds check here*/) 
             {
                 return _array[_start + index];
             }    
         }
     }
}

这不是一个数组,而是一个数组的投影。

答案 1 :(得分:2)

您可以使用ArraySegment。这是一个例子:

String[] X = { "one", "two", "three", "four", "five"};

ArraySegment<String> arraySegment = new ArraySegment<String>(X, 1,3); // will contain {"two", "three", "four"}
arraySegment.Array[arraySegment.Offset + 1] = "3"; // X will contain { "one", "two", "3", "four", "five"};
                             // and arraySegment.Array will contain {"two", "3", "four"}

答案 2 :(得分:0)

可悲的是ArraySegment<T>已被封存,否则您可以轻松地使用正确的数组语法扩展它,即索引器等。

如果我是你,我会选择ArraySegment<T>,如果它没有正确的要求,例如ElementAt(n)效率低下,只需实施更好的实施。例如:

public static class ArrayExtensions 
{
  // Getter using underlying array
  public static T GetValueAt<T>(this ArraySegment<T> array, int index)
  { // No safe checks here, would recommend them in production though
    return array.Array[array.Offset + index];
  }
  // Setter using underlying array
  public static void SetValueAt<T>(this ArraySegment<T> array, int index, T value)
  { // maybe we should check that the calculated index is valid? Or just blow up?
    array.Array[array.Offset + index] = value;
  }
}