C# Массив среза без копирования
Я хотел бы передать подмножество массива C# в метод. Мне все равно, если метод перезаписывает данные, поэтому хотел бы избежать создания копии.
Есть ли способ сделать это?
Благодарю.
4 ответа
Измените метод, чтобы взять IEnumerable<T>
или же ArraySegment<T>
,
Затем вы можете пройти new ArraySegment<T>(array, 5, 2)
С 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, взять функцию и взять столько элементов из массива, сколько вы хотите
var yournewarray = youroldarray.Take(4).ToArray();