Unfortunately you can't. From the language specification:
For example, the following .NET types support both indices and ranges: String, Span, and ReadOnlySpan. The List supports indices but doesn't support ranges.
Type Support for ranges and indices.
So the only way would be something like this, which is a bit clunky:
var subList = list.ToArray()[0..1];
Edit: I will leave the rest of my answer here for the record, but I think the answer using Range
is more elegant, and will be significantly faster, especially for large slices.
Benchmarking and Extension Method
The following demonstrates how much slower using ToArray()
can be (using LINQPad - F.Rnd.Str
is my own helper method for generating random strings):
var list = new List<string>();
for (int i = 0; i < 100000; i++)
{
list.Add(F.Rnd.Str);
}
// Using ToArray()
var timer = new Stopwatch();
timer.Start();
var subList0 = list.ToArray()[42..142];
timer.Stop();
timer.ElapsedTicks.Dump("ToArray()");
// Using Indices
timer.Reset();
timer.Start();
var subList1 = new List<string>();
for (int i = 42; i < 142; i++)
{
subList1.Add(list[i]);
}
timer.Stop();
timer.ElapsedTicks.Dump("Index");
// ToArray()
// 3136
// Index
// 28
Therefore an extension method like this will be very quick:
public static class ListExtensions
{
public static List<T> GetSlice<T>(this List<T> @this, int first, int last)
{
var slice = new List<T>();
for (int i = first; i < last; i++)
{
slice.Add(@this[i]);
}
return slice;
}
}
Then you can add this to the benchmark:
// Using Extension Method
timer.Reset();
timer.Start();
var subList2 = list.GetSlice(42, 142);
timer.Stop();
timer.ElapsedTicks.Dump("Extension");
Benchmark results:
// ToArray()
// 2021
// Index
// 16
// Extension
// 15
Range
One of the answers uses Range
to achieve the same thing, so for comparison:
timer.Reset();
timer.Start();
var range = new Range(42, 142);
var (start, length) = range.GetOffsetAndLength(list.Count);
var subList3 = list.GetRange(start, length);
timer.Stop();
timer.ElapsedTicks.Dump("Range");
Benchmark results:
// ToArray()
// 2056
// Index
// 21
// Extension
// 16
// Range
// 17
You can see the bottom three methods are essentially the same in terms of speed (as I run it multiple times they all vary between 15-21 ticks).