C# 8: Indexes and Ranges
Index and ranges gives you another way to access elements in an array.
C# 8.0 Series
Want to read my other posts about C# 8?
- C# 8: nullable reference types.
- C# 8: Indexes and Ranges.
- C# 8: Using statement revisited!
Prerequisites & Setup
You will need Visual Studio 2019 and .NET Core 3.0 SDK to try out indexes and ranges. We need to modify the .csproj file to enable C# 8.0:
Let’s compare how we access specific elements in an array
Access elements is not something new. It’s fundamental to any programming language and thus also a concept in C#. Index is a new readonly struct added to the Framework.
I like to stick with cars in this post as well as I did in the previous C# 8 blog post. This time we have 10 parked cars that we get as an array:
The first (1) is a common way how we access elements inside an array. LINQ (2) is the most natural to read but that comes also with a (minimal) cost - It’s slower than the other solutions because it iterates over the elements from the start until the condition is met. But think about that readability is usually in most cases more important than performance. The last (3) uses the new “hat”-operator to express the new index type:
- [^7] means from the end count seven elements backwards.
- [^1] means from the end the first element.
Pay attention that [^0] is not valid and will throw an exception - because [^0] is equal to [array.Length - 0] and this throws an IndexOutOfRangeException. The [^7] and [^1] are shorthand versions of this:
Usually I want also understand how the compiler is emitting my C# code and how the .NET Runtime is handling it. You maybe wonder if [^1] is compiled to [array.Length - 1]. It is almost the same. Decompiling the assembly with IL-Spy proves this:
The critical IL-Operation is the same as well:
By int:
By Index:
Access a range of specific elements
Let’s combine two indexes to form a range - makes sense, right?
Range is a readonly struct and a new type. It consists mainly of a Start and End property of type Index. The following code is usually what we do to get a range out of a string using Substring():
With ranges you can express exactly the same in a slightly different way:
It compiles internally to a call to Substring().
Closing words
I’m curious how this feature will change the way I or other developers write code in C#. In my opinion it’s very convenient in some situations - especially the Range. But compared to other features it’s not something completely new that you couldn’t do with a lower C# version. Simply because these two operators will be lowered to regular indexer/method calls.