Object initializers with indexes
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.