5

I'm refactoring a library we currently use, and I'm faced with the following problem.

We used to have the following stuff :

class Blah
{
    float[][] data;
    public float[] GetDataReference(int index)
    {
        return data[index];
    }
}

For various reasons, I have replaced this jagged array version with a 1 dimensionnal array version, concatenating inner arrays. My question is : how can I still return a reference to a sub array of data ?

class Blah
{
    float[] data;
    int rows;

    public float[] GetDataReference(int index)
    {
        // Return a reference data from offset i to offset j;
    }
}

I was thinking that unsafe and pointers stuff may be of use, is it doable ?

2 Answers 2

10

No, you can't do this - but you should look at using ArraySegment instead.

Note that an array object consists of metadata about its length etc and then the data itself. You can't create a slice of an existing array and still have the metadata next to the data, if you see what I mean - there'd have to be an extra level of indirection (which is what ArraySegment provides).

(I'm slightly surprised that ArraySegment doesn't do more wrapping, e.g. by implementing IList<T>, but there we go. It would be easy enough to create such a structure if you wanted to.)

Sign up to request clarification or add additional context in comments.

7 Comments

Agreed, didn't know that either. I'll keep my answer (should work as well), but this seems to be the "right way" (tm)
The memory layout of a jagged array makes it impractical to use unsafe constructs to get to their contents. If multiple dimensional arrays were used, it can be done and can be beneficiary in (rare) corner cases where the poor .NET performance on multi dim arrays is too slow for you. But you still cannot return a slice without copying and adding the new metadata.
@Abel: I understand that it is not jagged, just a long single-dimensional array. Think the ImageData bytes[] that you have to map to rows again to get something at a specified x, y. That's how I got him at least.
Hum, I have already created a wrapper with some kind of IArray<T> : IEnumerable<T> interface. Works nicely but means that I'll have to change/check all calls to GetDataReference in the code... even some code I have no access to..
An ArraySegment class which could be used interchangeably with an array would be wonderful, but would require CLR support. ArraySegment and ReadonlyArraySegment structs which supported indexing operators, IEnumerable, and widening casts from array types would be nice too. Since ArraySegment doesn't support much of anything, I'm unclear what it's good for.
|
1

Check the following question on SO, but don't use the accepted answer (you don't want to copy after all), but rather follow the other options of using an Enumerator for the slice/subpart of the original array.

Array slices in C#

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.