C#数组切片没有副本

时间:2013-01-14 18:01:56

标签: c# arrays performance slice space-efficiency

我想将一个C#数组的子集传递给一个方法。我不在乎该方法是否会覆盖数据,因此我们希望避免创建副本。

有办法做到这一点吗?

感谢。

5 个答案:

答案 0 :(得分:14)

将方法更改为IEnumerable<T>ArraySegment<T>

然后您可以传递new ArraySegment<T>(array, 5, 2)

答案 1 :(得分:2)

数组是不可变的大小(即你不能改变数组的大小),所以你只能传递原始数组的减去副本。作为选项,您可以将原始数组旁边的两个索引传递给方法,并在另外两个索引的基础上运行。

答案 2 :(得分:2)

您可以使用以下课程。请注意,您可能需要根据您是希望endIndex包含还是独占来修改它。您也可以修改它以获取开始和计数,而不是开始和结束索引。

我故意没有添加可变方法。如果你特意想要他们,这很容易添加。如果添加可变方法,您可能还想实现IList

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();
    }
}

答案 3 :(得分:2)

有了C#7.2,我们有了Span<T>。您可以为数组使用扩展方法AsSpan<T>并将其传递给该方法,而无需复制切片的部分。例如:

Method( array.AsSpan().Slice(1,3) )

答案 4 :(得分:-3)

你可以使用Linq带来funktion并根据需要从数组中获取尽可能多的元素

var yournewarray = youroldarray.Take(4).ToArray();