C# 8.0 brings us another nice feature called slicing. In order to make it possible, two new concepts are introduced: Indexes and Ranges.

Let’s see how this tiny feature is supposed to make our life easier 🙂

Goal of slicing

The main purpose of introducing slicing into the language is to make working with arrays and strings easier.

Currently, when you want to retrieve a fragment of an array (X elements from the array, located for instance in its middle), you can use LINQ, i.e. combination of Take and Skip methods. You can also create some extension method to provide kind of slicing.

To illustrate the current way, using LINQ to retrieve only 2nd, 3rd and 4th elements of an array looks as follows:

C# community and designers decided it’s not convenient enough, so are now adding to C# 8 indexes and ranges (in order to provide slicing) 🙂

Index

C# 8.0 comes along with a new object – System.Index. It’s a structure internally and looks as follows:

System.Index structure – .NET Core 3.0.0-preview-27324-5

What’s interesting here, is that the constructor takes the value of the index and boolean flag fromEnd. Let’s see how we can use it in practice:

While the first printed value is nothing special, as you can see we can now use the hat operator (^) in order to index from the end. The following also works:

It means that the ^ operator is a syntactic sugar for Index. I allowed myself to check the IL produced:

IL Code behind ^ (hat operator)

As we suspected – an instance of Index is created, passing 3 as value and true as fromEnd (see the constructor parameters above).

Range

Another concept which uses Indexes is a new structural data type – System.Range:

System.Range structure – .NET Core 3.0.0-preview-27324-5

As you can see, it really uses Indexes. We can even try creating it on our own:

This doesn’t really make extracting data from the arrays better than Skip-Take LINQ, does it?

Fortunately, there’s another friendly C# language element introduced called range expression. It can be written as x..y and used directly for indexing:

This looks much better! Let’s see how C# compiler translated our 2 lines of code by looking at the pseudo-C# IL produced:

IL (C# pseudo-code) produced when using range expression

Even though we could achieve the same with much less LINQ, C# compiler does a lot of stuff for us, keeping our code simpler to grasp.

Ranges in strings

All these operations apply also to strings:

Ranges in foreach loop

Next interesting usage is in the foreach loop:

Summary

I see these “little” C# 8 indexes and ranges as another helpful feature. It’s less breaking and controversial than nullable reference types, still making us write less C# code in the future.

If you’d like to dig the feature even more, I encourage you to read the discussions about it on GitHub, which I always find very interesting 😉

Developers, what do you think about C# 8 indexes and ranges? 🤔