我希望将 C# 数组的子集传递给方法,但不关心方法是否会覆盖数据,因此想避免创建副本。有没有办法做到这一点?谢谢。
将方法更改为接受 IEnumerable<T>
或 ArraySegment<T>
。
然后可以传递 new ArraySegment<T>(array, 5, 2)
IEnumerable<T>
的示例,其中包含Skip
/ Take
。 - Stefan SteineggerArraySegment<T>
实现了 IEnumerable<T>
。 - SLaksArraySegment<T>
是 O(1)。http://referencesource.microsoft.com/#mscorlib/system/arraysegment.cs#164 - SLaks在 C# 7.2 中,我们有了 Span<T>
。您可以使用扩展方法 AsSpan<T>
对数组进行切片,并将其传递给方法,而无需复制切片部分。例如:
Method( array.AsSpan().Slice(1,3) )
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();
}
}
数组大小不可变(即无法更改数组的大小),因此您只能传递原始数组的一个减去后的副本。作为选项,您可以将两个索引与原始数组一起传递到方法中,并基于这两个额外的索引进行操作。
你可以使用 Linq 的 Take 函数,从数组中取出任意数量的元素。
var yournewarray = youroldarray.Take(4).ToArray();
ToArray
,则会执行一次拷贝。您还需要同时使用 Skip
和 Take
来获取任意子集。最后,如果他想要在子集内进行快速索引访问,则无法从 IEnumerable
中获得。 - Servy