2009-06-28 50 views
9

我正在使用C#,而且它很烦人,我无法从像C++这样的特定点开始发送数组。获取从偏移量开始的数组

想这代码:

int[] array = new int[32]; 
foobar (array + 4); //send array starting from the 4th place. 

这是一个奇怪的语法为C#,因为我们没有任何可用的指针,但肯定有办法做到这一点? 有.Skip(),但我认为它产生了一个新的数组,这是我不喜欢的。

我有什么选择?

+3

仅供参考,skip不会产生新的数组。它会生成一个新的_array枚举器,该枚举器跳过了前n个条目。 – 2009-06-29 01:47:18

+1

将C++代码移植到C#时,我使用内部指针的数组实现了一个不可变的ArrayPtr结构,该结构实现了用户定义的[] - +运算符。 ArrayPtr类处理详细信息,确定正确的偏移量到真实数组中的位置。 – 2009-06-29 01:49:27

+0

您是如何确定创建新阵列的开销太大? – nos 2009-06-29 15:47:31

回答

1

您可以将偏移量作为参数传递给函数本身。然后该函数将循环遍历从[array + offset]到array.Length的元素。那,或者将子数组复制到一个新的数组中,但这可能不是最优的。

17

您可能想将其作为IEnumerable<int>而不是数组传递给它。然后,您可以使用跳过,它将简单地将迭代器移到跳过的元素数量上。以这种方式使用,您不必使用ToArray()并创建相关数组部分的副本。当然,IEnumerable可能不适合你想要做的事情,但是很难从你的问题中得知。

public void FooBar(IEnumerable<int> bar) 
{ 
    ... 
} 

int[] array = new int[32]; 
FooBar(array.Skip(4)); 
3

我可以理解你正在尝试做的,但你不能(也不应该尝试)发送一个参考“的阵列的一部分。”在C#中,数组是对象,而不是指针。这是一个重要的区别。发送对“部分对象”的引用没有任何意义。

当一个对象的一部分传递给某个方法时,该如何处理这个对象?

  • array.Length会返回什么?
  • 如果调用方法对数组进行排序(只是它是数组的一部分)会怎么样?
  • 如果数组是自引用的(即数组元素引用数组的其他部分)会怎么样?你是不知何故“锁定”访问数组元素而不是传入的方法?
  • 调用方法现在是否需要检查标志以确定它们是否具有“完整对象?”这会破坏很多现有的代码。

如果您的方法只需要数组的一部分(并且您不想创建本地副本),最好的解决方案是将数组引用和任何其他信息传递到您需要的部分需要。

享受,

罗伯特C. Cartaino

3

.NET有System.ArraySegment包装 - 不幸的是,因为它没有实现IEnumerable它是完全无用的。