tags:

views:

310

answers:

4

I am using C#, and it's rather annoying that I can't send an array starting from a certain point like in C++.

suppose this code:

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

this is a weird syntax for C# because we don't have any usable pointers, but surely there's a way to do it? There's .Skip(), but I think it produces a new array, which is something I do not like.

What are my options?

+1  A: 

You could just pass the offset to the function itself as a parameter. The function will then simply loop through the elements from [array + offset] to array.Length. That, or copy the sub-array into a new array, but that is probably not optimal.

Ed Swangren
yes, I know of that, but it's soo ugly.
Nefzen
Yeah, I like tv's suggestion better, but I don't know about "so ugly". It is pretty straitforward, what do you think array.Skip is doing?
Ed Swangren
the thing is that it's error prone
Nefzen
+10  A: 

You might want to pass it as an IEnumerable<int> rather than as an array. You can then use skip and it will simply move the iterator over the number of elements skipped. Used this way, you won't have to use ToArray() and create a copy of the portion of the array in question. Of course, IEnumerable may not be appropriate for what you want to do, but that's difficult to tell from your question.

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

int[] array = new int[32];
FooBar( array.Skip(4) );
tvanfosson
what's the overhead for turning an array into an enumerable?
Nefzen
Zero - arrays already implement IEnumerable<T>
tvanfosson
http://msdn.microsoft.com/en-us/library/system.array.aspxIn the .NET Framework version 2.0, the Array class implements the System.Collections.Generic.IList(T), System.Collections.Generic.ICollection(T), and System.Collections.Generic.IEnumerable(T) generic interfaces. The implementations are provided to arrays at run time, and therefore are not visible to the documentation build tools.
tvanfosson
Wouldn't have thought of this approach in a million years. Really elegant. +1
JulianR
and the other way around? if I turn an Enumerable to an Array?
Nefzen
I'm pretty sure that it will make a copy of the elements in the enumeration and return it as an array.
tvanfosson
+2  A: 

I can appreciate what you are trying to do but you can't (and shouldn't try to) send a reference to "part of an array." In C#, arrays are objects, not pointers. That's an important distinction. Sending a reference to "part of an object" just doesn't make sense.

How should "part of an object" act when you pass it to a method?

  • What would array.Length return?
  • What if the called method sorts the array (just it's part of the array)?
  • What if the array is self-referential (i.e. array elements references other parts of the array)? Are you somehow "locked out" of accessing array elements not passed into the method?
  • Does the called method now need to check a flag to know if they have the "full object?" That would break a lot of existing code.

If your method needs only part of the array (and you don't want to create a local copy), the best solution would be to pass the array reference and any other information you need to access the portion you need.

Enjoy,

Robert C. Cartaino

Robert Cartaino
yes, an array reference would be good. The method doesn't need to know it's working on a subset of the array, it only reads or writes on it. A reference to an array with the same interface would be great. Actually I think I can write that myself, but I don't think it is worth the extra overhead.
Nefzen
+1  A: 

.NET has the System.ArraySegment wrapper – unfortunately, it's completely useless since it doesn't implement IEnumerable.

Konrad Rudolph