Skip to content

Ranges and indices C# 8.0readabilitycode reduction

Use `..` and `^` operators to slice collections and access elements from the end.

Accessing elements from the end of a collection or extracting a slice required verbose calculations or LINQ methods. This was especially cumbersome when working with the last few elements or specific ranges.

C# 8.0 introduces ranges and indices with two new operators: ^ for indexing from the end and .. for creating ranges. These operators provide a concise, readable syntax for slicing collections and are particularly powerful when combined with Span<T> and Memory<T> for high-performance scenarios.

Code

C#
var numbers = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int lastItem = numbers[^1];           // 10
int secondToLast = numbers[^2];       // 9

int[] firstThree = numbers[..3];      // { 1, 2, 3 }
int[] lastThree = numbers[^3..];      // { 8, 9, 10 }
int[] middle = numbers[3..7];         // { 4, 5, 6, 7 }
int[] allButFirstAndLast = numbers[1..^1]; // { 2, 3, 4, 5, 6, 7, 8, 9 }

// Can also store ranges in variables
Range middleRange = 3..7;
int[] subset = numbers[middleRange];
C#
var numbers = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

int lastItem = numbers[numbers.Length - 1];
int secondToLast = numbers[numbers.Length - 2];

int[] firstThree = numbers.Take(3).ToArray();
int[] lastThree = numbers.Skip(numbers.Length - 3).ToArray();
int[] middle = numbers.Skip(3).Take(4).ToArray();
int[] allButFirstAndLast = numbers.Skip(1).Take(numbers.Length - 2).ToArray();

Notes

  • The ^ operator creates an Index from the end: ^1 is the last element, ^2 is second-to-last, etc.
  • The .. operator creates a Range: the start is inclusive, the end is exclusive
  • Omitting the start (..3) means "from the beginning", omitting the end (3..) means "to the end"
  • Works with arrays, strings, Span<T>, Memory<T>, and any type with an indexer and Length or Count property
  • Using ranges with Span<T> creates slices without allocating new arrays, providing zero-allocation performance
  • Index and Range are structs in the System namespace and can be stored in variables

More information