创建指向另一个数组的一部分数组? [英] Create an array that points to only part of another array?

查看:171
本文介绍了创建指向另一个数组的一部分数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含引用类型元素一个巨大的数组,我想创造出很多其他阵列,基本上只是指向一个大数组的特定部分。

I have a huge array that contains reference type elements, and I want to create a lot of other arrays that essentially just point to specific parts of that one big array.

在换句话说,我要创建索引或有长度的指针。

In other words, I want to create "indexers" or "pointers with lengths".

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

In C++ it's easy to do so using pointers and for each pointer assign a length, for example create a struct which contains a pointer with a length.

我如何在C#中实现这一/。NET?

How can I achieve this in C#/.NET?

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

The whole point is to avoid copying anything, I just want pointers to specific parts in an array that already exists in memory.

任何想法?

推荐答案

使用乔恩的建议 ArraySegment< T> 可能是你想要的。然而,如果你想要一个指针重新present到阵列内部的方式,您可以在C ++中,这里的一些code表示。无担保前pressed或暗示的使用风险自担。

Jon's suggestion of using ArraySegment<T> is likely what you want. If however you are wanting to represent a pointer to the interior of an array, the way you can in C++, here's some code for that. No warranty is expressed or implied, use at your own risk.

这code不跟踪任何方式的内部指针的长度,但它是很容易的,如果你想添加这个功能。

This code does not track the "length" of the interior pointer in any way, but it is quite easy to add that feature if you want.

internal struct ArrayPtr<T>
{
  public static ArrayPtr<T> Null { get { return default(ArrayPtr<T>); } }
  private readonly T[] source;
  private readonly int index;

  private ArrayPtr(ArrayPtr<T> 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<T> a, ArrayPtr<T> b)
  {
    Debug.Assert(Object.ReferenceEquals(a.source, b.source));
    return a.index < b.index;
  }

  public static bool operator >(ArrayPtr<T> a, ArrayPtr<T> b)
  {
    Debug.Assert(Object.ReferenceEquals(a.source, b.source));
    return a.index > b.index;
  }

  public static bool operator <=(ArrayPtr<T> a, ArrayPtr<T> b)
  {
    Debug.Assert(Object.ReferenceEquals(a.source, b.source));
    return a.index <= b.index;
  }

  public static bool operator >=(ArrayPtr<T> a, ArrayPtr<T> b)
  {
    Debug.Assert(Object.ReferenceEquals(a.source, b.source));
    return a.index >= b.index;
  }

  public static int operator -(ArrayPtr<T> a, ArrayPtr<T> b)
  {
    Debug.Assert(Object.ReferenceEquals(a.source, b.source));
    return a.index - b.index;
  }

  public static ArrayPtr<T> operator +(ArrayPtr<T> a, int count)
  {
    return new ArrayPtr<T>(a, +count);
  }

  public static ArrayPtr<T> operator -(ArrayPtr<T> a, int count)
  {
    return new ArrayPtr<T>(a, -count);
  }

  public static ArrayPtr<T> operator ++(ArrayPtr<T> a)
  {
    return a + 1;
  }

  public static ArrayPtr<T> operator --(ArrayPtr<T> a)
  {
    return a - 1;
  }

  public static implicit operator ArrayPtr<T>(T[] x)
  {
    return new ArrayPtr<T>(x);
  }

  public static bool operator ==(ArrayPtr<T> x, ArrayPtr<T> y)
  {
    return x.source == y.source && x.index == y.index;
  }

  public static bool operator !=(ArrayPtr<T> x, ArrayPtr<T> y)
  {
    return !(x == y);
  }

  public override bool Equals(object x)
  {
    if (x == null) return this.source == null;
    var ptr = x as ArrayPtr<T>?;
    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; }
  }
}

现在,我们可以做的东西,如:

Now we can do stuff like:

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

这篇关于创建指向另一个数组的一部分数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆