Object initializers with indexes

August 30th 2024 C#

The thing that probably surprised me most when reading the official blog post about the new features in C# 13 was the support for index from the end in initializers. It was because I wasn't even aware that indexers were supported in object initializers.

Sure, I've initialized dictionaries using the indexer syntax before:

var dictionary = new Dictionary<int, string>
{
    [1] = "one",
    [2] = "two",
    [3] = "three",
};

But it never really occurred to me that I could use the same syntax for initializing any other type with an indexer implemented, as suggested in the following example in the documentation:

var thing = new IndexersExample
{
    name = "object one",
    [1] = '1',
    [2] = '4',
    [3] = '9',
    Size = Math.PI,
};

So, I implemented a matching type to try it out:

public class IndexersExample
{
    public string? name;
    public double Size { get; set; }

    private readonly char[] letters = new char[4];
    public char this[int i]
    {
        get { return letters[i]; }
        set { letters[i] = value; }
    }

    public int Length => letters.Length;
}

It worked as documented. I also added the Length property because it's required for indexes from the end to work. Despite that, in C# 12 those don't work in object initializers, but do when accessing the indexer later on:

thing[^1].Should().Be('9');

In C# 13, the same syntax now also works in the object initializer:

var thing = new IndexersExample
{
    name = "object one",
    [1] = '1',
    [2] = '4',
    [^1] = '9',
    Size = Math.PI,
};

I created a small sample project and pushed it to my GitHub repository. For the new syntax to work, you need to use the C# 13 compiler. In the current Visual Studio 2022 Preview version (17.12.0 Preview 1.0) it's already selected as the default. To use it in the latest non-preview Visual Studio 2022 version (currently 17.11.1), you need to choose the preview language version which I already did in the project file:

<LangVersion>preview</LangVersion>

Object initializers support setting values to indexers since they were originally introduced in C# 3. But when the indexes from the end were added to the language in C# 8, they weren't supported in object initializers. C# 13 fills that gap and adds support for indexes from the end also to the object initializers.

Get notified when a new blog post is published (usually every Friday):

Copyright
Creative Commons License