Index from the end and ranges
In a changing room, you find the last locker of a row without knowing its number: you walk to the end of the row. And you take the things from several neighboring lockers in one go, without naming the lockers one by one.
With an array, you cannot do that yet. To read the last element, you have to work out its index: nums[nums.Length - 1]. And to take several elements in a row, you need a loop that copies them into a new array. C# has short forms for both cases.
An index from the end
You can get the last element in a shorter way: nums[^1]. The ^ sign before a number makes it an index from the end, and ^n means "the n-th element from the end":
^1is the last element, the same as indexLength - 1;^2is the one before the last.
Counting from the end starts at one, not at zero. ^0 points to the spot right after the last element, like the index Length.
A range
The range nums[1..3] takes a part of the array: the elements from index 1 to index 3. The start is in the range and the end is not, so these are the elements at indexes 1 and 2. Either bound, or both, can be left out:
nums[..2]runs from the start to index2: the first two elements;nums[3..]runs from index3to the end of the array;nums[^2..]is the last two elements;nums[..]is the whole array, from start to end.
int[] nums = [10, 20, 30, 40, 50];
Console.WriteLine(nums[^1]); // 50
int[] middle = nums[1..3];
Console.WriteLine(string.Join(", ", middle)); // 20, 30
Console.WriteLine(string.Join(", ", nums[..2])); // 10, 20
Console.WriteLine(string.Join(", ", nums[3..])); // 40, 50
middle[0] = 99;
Console.WriteLine(nums[1]); // 20A range of an array creates a new array and copies the elements into it. So middle[0] = 99 changes only the copy, and nums[1] is still 20.
nums[..] works the same way: it is a copy of the whole array. If you need a sorted array and the old order too, keep a copy, int[] sorted = nums[..];, and sort it with Array.Sort.
Here the locker picture is not quite right. In a changing room, "lockers 1 and 2" are the very same lockers. A range of an array sets up a new, shorter row and puts copies of the things into it.
Interviewers like to ask whether the end of a range is part of the result. It is not: nums[1..3] has 3 - 1 elements, that is, two.
Common mistake
Someone tried to read the last element with ^0:
int[] nums = [10, 20, 30];
Console.WriteLine(nums[^0]); // ✗Unhandled exception. System.IndexOutOfRangeException: Index was outside the bounds of the array.The program compiles, but when it runs, it stops at this line with an IndexOutOfRangeException. ^0 points past the last element, because counting from the end starts at one. The last element is nums[^1].
Key points
nums[^1]is the last element: counting from the end starts at one, and^0points past the end of the array.nums[1..3]is a new array of the elements at indexes1and2: the end of the range is left out, and changing the copy leaves the original alone.nums[..]is a copy of the whole array.