C# 8 – Excelling at Indexes
Time to read: 4 minutes
“There are only two hard problems in computer science: cache invalidation, naming things, and off-by-one errors.” — Riff on a joke by Phil Karlton
After this post, one of these problems will become a little easier for you to solve: you’re going to learn about indices and ranges. While nearly everyone programming in C# uses standard indexes on a regular basis, there are some new ways of accessing arrays and lists that can make your development life a little bit easier. In a few minutes you’ll be up to speed on this C# 8.0 feature and more prepared to take on the C# 9.0 release.
Review
One of the first things you learn as a beginning programmer in any language is how to access an array. Most languages use a 0-based index. Some languages use 1-based array indexes (and are wrong), but the basic syntax is similar. Here are a few examples from different languages:
C#
JavaScript
Python
While the basic syntax is the same, each language does things a little differently. In C#, Arrays are reference types, just like the other built-in collection types. They inherit from the object class and have a variety of different built in properties and methods. The array index syntax in C# is enabled by a feature called an indexer. Because indexers are a standard C# feature, they can be added to any custom object and are present on many array-like types such as Lists and Spans.
You can see working examples of different array-like objects in C# in the following code block. To run this code, spin up a new console app in Visual Studio 2019 or Visual Studio Code, or you can copy the code into an online IDE. .NET Fiddle is excellent for playing with new features and trying out code snippets, but be sure to set the Compiler field to .NET Core 3.1.
The index from end operator
While C# is versatile, there’s still some stuff that, until now, was only available in other languages. For example, languages like Python and Ruby allow you to use negative array indexes to access arrays in reverse.
Python
C# doesn’t support this, but C# 8.0 introduced a new feature that gets you the same functionality. This new operator is called the index from end operator: ^
. By adding a ^
before your array index value, C# will start at the end of the array and count backward to locate an element. ^1
refers to the last element in the array.
This functionality is supported by the new System.Index struct. This struct was introduced in .NET Core 3.0 to support the new index from end syntax. This means you can store indexes as variables in your code.
Here are a few examples for you to try out:
It’s just like using a negative index in other languages, just with a little bit different syntax. While this feature may not seem revolutionary on it’s own, it combines well with the next topic, Ranges.
Ranges
Another feature that’s common in other languages — including Ruby, Kotlin, F#, and Perl — is the ability to declare a range variable. Beginning with C# 8, you have the ability to declare a range. The Range struct contains a start and end index and allows you to use a single statement to slice chunks out of an indexable data structure.
In addition to the struct, C# has also introduced a new operator to make it look like other languages. The C# range operator looks like this: ..
and is used like this: 1..3
. The first number is the start index, which is inclusive. If you pick 1, it’ll start with the array[1]
. The second number is the end index. The end index is exclusive. For example, a range of 1..1
will return nothing.
Here are a few examples of the range operator in action:
The Range struct gives you a terse way to slice out chunks of an array. You can use it anytime you need to do an array slice. The example below uses from end indexing and ranges to average random samples from a data set. The amount of easy-to-mess-up array index math is vastly diminished when using these new operators.
The output will be a Double like 61.1. Your mileage will be an average of pseudorandom signed Int32 values between 30 and 80, inclusive. I’d be stoked if my crossover got that kind of mileage.
Gotchas
As you learned above, different objects in C# use indexers. Most of those objects support the new Range and Index options; some do not. For example, the List object will work with a from end index, but it will not work with a range.
When it comes to arrays, your garden variety single dimension arrays support ranges and indexes, but multidimensional arrays do not. However, jagged arrays (arrays of arrays) support both.
Fortunately, the compiler catches these errors, so you don’t have to wait until runtime to find out if you made a mistake. It would be nice if everything worked with everything, but if it was easy, someone would program a computer to do it.
Summary
One of the great things about being a .NET developer is that if you see something cool in another platform, it’s usually only a matter of time before it will show up in C#. From end indexing and ranges are both pieces of syntax found in other languages that have found their way into the .NET family.
The next time you need to do some advanced array access, try out these new ways of slicing and dicing your data. Then you can focus more of your time dealing with cache invalidation and naming things.
Additional resources
Check out the following resources to dive deeper into the topics discussed in this post:
Microsoft Docs – What’s new in C# 8 – Indices and ranges
Microsoft Docs – C# Tutorials – Type support for indices and ranges
Microsoft Docs – C# Programming Guide – Using indexers
Quotes on Design – Looking for more piquant and memorable quotations about software and graphic design? Check out this edifying, minimalist source.
Dustin Ewers is a software developer hailing from Southern Wisconsin. He helps people build better software. Dustin has been building software for over 10 years, specializing in Microsoft technologies. He is an active member of the technical community, speaking at user groups and conferences in and around Wisconsin. He writes about technology at https://www.dustinewers.com. Follow him on Twitter at @DustinJEwers.
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.