Ever wanted simple syntax for slicing out a part of an array, string or span? Now you can!
Let's consider the following program:
using System.Collections.Generic;
using static System.Console;
class Program
{
static void Main(string[] args)
{
foreach (var name in GetNames())
{
WriteLine(name);
}
}
static IEnumerable<string> GetNames()
{
string[] names =
{
"Christopher", "Natasha", "Jean", "Matthew", "Luke"
};
foreach (var name in names)
{
yield return name;
}
}
}
As you might expect, this program just prints the 5 names in the console.
Ranges and Indices
With new Ranges syntax, we can modify the foreach
to iterate over names 1 to 4. For example:
foreach (var name in names[1..4])
The endpoint is exclusive (element 4 is not included). 1..4
is actually a range expression, and it doesn't have to occur like here, as part of an indexing operation. It has a type of its own, called Range
. If we wanted, we could pull it out into its own variable, and it would work the same:
Range range = 1..4;
foreach (var name in names[range])
The endpoints of a range expression don't have to be int
s. In fact they're of a type, Index, that non-negative int
s convert to. But you can also create an Index
with a new ^
operator, meaning "from end". So ^1
is one from the end:
foreach (var name in names[1..^1])
This lobs off an element at each end of the array, producing an array with the middle three elements, so the result would be:
Natasha
Jean
Matthew
Range expressions can be open at either or both ends. ..^1
means the same as 0..^1
. 1..
means the same as 1..^0
. And ..
means the same as 0..^0
: beginning to end. Try them all out and see! Try mixing and matching "from beginning" and "from end" Indexes at either end of a Range and see what happens.