How it works
An index from the end uses the caret syntax. The last element is at index ^1, because ^0 represents the position immediately after the final element. A range describes a start and an exclusive end. Exclusive ends make adjacent slices fit together naturally: the element at the end position belongs to the next slice, not to the current one.
The meaning of slicing depends on the receiver type. Slicing an array with range syntax creates a new array containing the selected elements. A span slice is a view over existing storage instead. This lesson uses arrays, so changing the returned slice does not change the original array. Keeping the storage model explicit is as important as remembering the punctuation.
Walk through the example. The program first reads the final value with ^1. The range 1..4 selects elements at positions one, two, and three, producing twenty, thirty, and forty. The final range selects the last two values. Updating the copied middle slice then demonstrates that the original array remains unchanged at its corresponding position.
Watch the boundary. A range whose bounds do not fit the sequence is an error, and a last-element access is invalid on an empty array. Do not use ^1 until the nonempty condition is established. Remember that ^2 means a position measured from the end, not a negative integer index. Write out concrete indices when reviewing a slice that combines both forms.
Practice independently. Write a function that returns the middle portion of an integer array after dropping the first and last elements. Define behavior for arrays of length zero, one, and two before coding. Test odd and even lengths, and verify that modifying the returned slice does not alter the original. Then express a last-three-items operation that safely handles arrays shorter than three elements.
A working example
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
int[] values = { 10, 20, 30, 40, 50 };
Console.WriteLine(values[^1]);
int[] middle = values[1..4];
Console.WriteLine(string.Join(",", middle));
Console.WriteLine(string.Join(",", values[^2..]));
middle[0] = 99;
Console.WriteLine(values[1]);
Expected output
50 20,30,40 40,50 20
The end of a range is excluded; array slices allocate separate array storage.