C# 8.0 Indices and ranges
Tags: dotnet, csharp, aspnet, dotnetcore
Published: 2020-03-22 01:02:58

## Also in this [series](https://blog.miguelbernard.com/csharp-8-0-new-features/)

1. [C# 8.0 Nullable Reference types are here!](https://blog.miguelbernard.com/c-8-0-nullable-reference-types-are-here/)
2. [Pattern matching in C#](https://blog.miguelbernard.com/pattern-matching-in-csharp/)
3. [Asynchronous streams](https://blog.miguelbernard.com/asynchronous-streams/)
4. [Indices and ranges](https://blog.miguelbernard.com/c-8-0-indices-and-ranges)
5. [Default interface methods](https://blog.miguelbernard.com/what-are-default-interface-methods-in-c-8-0)
6. [5 tips to improve your productivity in C# 8.0](https://blog.miguelbernard.com/5-tips-to-improve-your-productivity-in-c-8-0)

> All code samples are available on [github](https://github.com/mbernard/csharp8sample)

Compared to other languages, C# was way behind in capabilities to handle data efficiently. Well, those days are over now. Microsoft just improved the C# syntax, making it easier for developers to manage data in arrays.

# Manipulating Arrays

Have you ever had to manipulate a large set of data in multiple arrays? Of course, you have! And I guess your experience wasn't that good. Compared to other languages, C# was way behind in capabilities to handle data efficiently. Well, those days are over now. Microsoft just improved the C# syntax, making it easier for developers to manage data in arrays.

## The new guys

Two new operators have been introduced in C# 8.0 to give you all the power you need:

- The 'index from the end' operator: `^`, which specifies that an index is relative to the end of the sequence; and
- The 'range' operator: `..`, which specifies the start and end of a range.

### Important notes

- The `^0` index is the same as `sequence[sequence.Length]`.
  - Be careful, `sequence[^0]` **does** throw an `IndexOutOfRangeException`, just as `sequence[sequence.Length]` does.
- For any number **n**, the index `^n` is the same as `sequence.Length - n`.
- For ranges, the start of the range is **inclusive**, but the end of the range is **exclusive**.
- The range `[0..0^]` represents the entire sequence, just as `[0..sequence.Length]` or `[..]`.
- A range doesn't need to be completely defined, e.g.
  - `[..3]` -> give me everything from the start of the array to index `3`.
  - `[2..]` -> give me everything from index `2` until the end of the array.
  - `[..]` -> give me everything

## Examples

Confused? I promise it will all make sense after this. Let's look at a few examples.

```csharp
private string[] words = new string[]
{
                // index from start    index from end
    "The",      // 0                   ^9
    "quick",    // 1                   ^8
    "brown",    // 2                   ^7
    "fox",      // 3                   ^6
    "jumped",   // 4                   ^5
    "over",     // 5                   ^4
    "the",      // 6                   ^3
    "lazy",     // 7                   ^2
    "dog"       // 8                   ^1
};

```

> As you can see here `words[^0]` is equal to `words[9]`, which is out of range

### Give me some more

Alright, alright. Here are some more ways to use it.

```csharp
var allWords = words[..]; // contains "The" through "dog".
var firstPhrase = words[..4]; // contains "The" through "fox".
var lastPhrase = words[6..]; // contains "the, "lazy" and "dog".
var lazyDog = words[^2..^0]; // contains "lazy" and "dog".
```

`Index` and `Range` are also .NET types, which means you can create variables of those types, name them for code clarity, and reuse them over and over.

```csharp
Index the = ^3;
words[the];

Range phrase = 1..4;
words[phrase];
```

## Conclusion

This is super powerful, I can't wait to use it in my projects. This will help so much with reducing noise when using index calculations as well as making the code more maintainable. Thank you Microsoft for this great addition to the language ❤️.

### References

- [https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8](https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-8)

## Also in this [series](https://blog.miguelbernard.com/csharp-8-0-new-features/)

1. [C# 8.0 Nullable Reference types are here!](https://blog.miguelbernard.com/c-8-0-nullable-reference-types-are-here/)
2. [Pattern matching in C#](https://blog.miguelbernard.com/pattern-matching-in-csharp/)
3. [Asynchronous streams](https://blog.miguelbernard.com/asynchronous-streams/)
4. [Indices and ranges](https://blog.miguelbernard.com/c-8-0-indices-and-ranges)
5. [Default interface methods](https://blog.miguelbernard.com/what-are-default-interface-methods-in-c-8-0)
6. [5 tips to improve your productivity in C# 8.0](https://blog.miguelbernard.com/5-tips-to-improve-your-productivity-in-c-8-0)

> All code samples are available on [github](https://github.com/mbernard/csharp8sample)