Introduction
C# 8 has been released recently along with .NET Core 3.0, and it has several new features and enhancements to give more power to developers and make their day-to-day coding even easier. At the time of writing this article, C# 8 is available as preview version 5.
I have started writing a series of articles to go through the new C# 8 features one by one, and I have covered all the new features and enhancements. In case you have not gone through my first article about C# 8, you may go through it here.
In this article, we will go through the Ranges and indices.
Range and Indices are great additions to the C# world. Due to these constructs, handling indexes has become fairly easy. Below is a summary of the changes in this feature.
- The index represents an index in an array or sequence.
- The ^ operator specifies the relative index from the end of an array.
- The range represents a subrange of an array.
- The Range operator specifies the start (Inclusive) and end (exclusive) of a range.
The following table states the comparison of old and new syntax.
Task |
Old-style (Before C# 8) |
New style (in C# 8) |
Getting the second element from an array |
array[2] |
array[2] or Index idx = 2; array[idx] |
Getting third, the last element of an array |
array[array.Length-3] |
array[^3] |
Get the sub-range of an array from element index 2 to 4 |
array.ToList().GetRange(2, 3); |
array[2..5] or Range range= 2..5; array[range] |
Get the sub-range of an array from the second last element till the last element |
array.ToList().
GetRange(weeks.Length- 2, 2);
|
array[^2..^0]; or array[^2..]; or Range range= ^2..^0;
array[range]
|
Get the first three elements of an array. |
array.ToList().GetRange(0, 3); |
array[..3]; |
Now, let's take an example to understand this more and start with the traditional style as follows.
static string[] weeks = new string[]
{
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
};
public static void ExecuteOldRangeIndicesHandling()
{
Console.WriteLine($"Third element of an array is: {weeks[2]}");
Console.WriteLine($"Second last element of an array is: {weeks[weeks.Length - 2]}");
var midWeeks = weeks.ToList().GetRange(2, 3);
Console.WriteLine("Elements of midWeeks array are:");
foreach (var week in midWeeks)
{
Console.WriteLine(week);
}
var endOfWeeks = weeks.ToList().GetRange(5, 2);
Console.WriteLine("Elements of endOfWeeks array are:");
foreach (var week in endOfWeeks)
{
Console.WriteLine(week);
}
}
Let's have a look at the modern C# 8 code syntax to achieve the same as follows.
public static void ExecuteNewRangeIndicesHandling()
{
Index idx = 2;
Console.WriteLine($"\nThird element of an array is: {weeks[idx]}\n");
Console.WriteLine($"Second last element of an array is: {weeks[^2]}\n");
Range range = 2..5; // Start from 2nd index and go before 5th index means index 2, 3, and 4
var midWeeks = weeks[range];
Console.WriteLine("Elements of midWeeks array are:");
foreach (var week in midWeeks)
{
Console.WriteLine(week);
}
Console.WriteLine("\nElements of endofWeeks array are:");
var endofWeeks = weeks[^2..^0];
foreach (var week in endofWeeks)
{
Console.WriteLine(week);
}
}
Finally, let's go through the improvement in terms of unbounded arrays. With C# 8, you can just give one end to get a subrange in an array as follows.
public static void ExecuteUnboundedRange()
{
var midWeeks = weeks[..3]; // Start from 0th and goes before 3rd index means index 0, 1, and 2
Console.WriteLine("First three elements of midWeeks array are:");
foreach (var week in midWeeks)
{
Console.WriteLine(week);
}
Console.WriteLine("Last two elements of endofWeeks array are:");
var endofWeeks = weeks[^2..];
foreach (var week in endofWeeks)
{
Console.WriteLine(week);
}
}
Conclusion
You can clearly see that C# 8 syntax is more crisp and easy to use. The new syntax is clearer to know what subrange is being used. This can be pretty useful when performing analysis on the subrange of an array or sequence. One of the scenarios of using the Indices and Ranges is calculating the moving average in a loop.