Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# Array slice without copy

I'd like to pass a sub-set of a C# array to into a method. I don't care if the method overwrites the data so would like to avoid creating a copy.

Is there a way to do this?

Thanks.

like image 643
user1400716 Avatar asked Jan 14 '13 18:01

user1400716


3 Answers

Change the method to take an IEnumerable<T> or ArraySegment<T>.

You can then pass new ArraySegment<T>(array, 5, 2)

like image 135
SLaks Avatar answered Nov 15 '22 15:11

SLaks


With C# 7.2 we have Span<T> . You can use the extension method AsSpan<T> for your array and pass it to the method without copying the sliced part. eg:

Method( array.AsSpan().Slice(1,3) )
like image 22
uygar donduran Avatar answered Nov 15 '22 14:11

uygar donduran


You can use the following class. Note you may need to modify it depending on whether you want endIndex to be inclusive or exclusive. You could also modify it to take a start and a count, rather than a start and an end index.

I intentionally didn't add mutable methods. If you specifically want them, that's easy enough to add. You may also want to implement IList if you add the mutable methods.

public class Subset<T> : IReadOnlyList<T>
{
    private IList<T> source;
    private int startIndex;
    private int endIndex;
    public Subset(IList<T> source, int startIndex, int endIndex)
    {
        this.source = source;
        this.startIndex = startIndex;
        this.endIndex = endIndex;
    }

    public T this[int i]
    {
        get
        {
            if (startIndex + i >= endIndex)
                throw new IndexOutOfRangeException();
            return source[startIndex + i];
        }
    }

    public int Count
    {
        get { return endIndex - startIndex; }
    }

    public IEnumerator<T> GetEnumerator()
    {
        return source.Skip(startIndex)
            .Take(endIndex - startIndex)
            .GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
like image 45
Servy Avatar answered Nov 15 '22 16:11

Servy