Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

StringBuilder initializer works one way in VS2015 but another in VS2013

I have the following line of code, with works in VS 2015 and .Net 4.0, but I am getting an error in VS 2013.

StringBuilder s = new StringBuilder("test") {[0] = 'T'};

Why it works in a different way?

like image 880
Sergey Malyutin Avatar asked Dec 18 '14 15:12

Sergey Malyutin


1 Answers

Basically, object initializer expressions don't support indexing in C# 5 (which is what VS2013 supports). This is a new feature in C# 6.

In C# 6, your code is equivalent to:

StringBuilder tmp = new StringBuilder(); // Compiler-generated 
tmp[0] = 'T';
StringBuilder s = tmp;

There's no single-expression equivalent of this in C# 5... although of course you can just use new StringBuilder("T") to achieve the same result...

The most obvious use case for this would be Dictionary<,> - but I'd argue that usually it's a better idea to use the "old style" object initializer syntax for that, which ended up calling Add:

var dict = new Dictionary<string, int>
{
    { "key1", 10 },
    { "key2", 20 }
};

The indexer-based equivalent of that is:

var dict = new Dictionary<string, int>
{
    ["key1"] = 10,
    ["key2"] = 20
};

... but the disadvantage here is that if you supply two equal keys, the second will happily overwrite the first, as that's the behaviour of the Dictionary<,> indexer... whereas with Add, an exception will be thrown instead. Given that in an object initializer you almost always want to specify distinct keys, the Add approach gives more protection against bugs than the indexer approach.

Where this feature will be useful, however, is for types which have an indexer but no (working) Add method. For example, a fixed-length collection might well support element replacement but not addition.

For more details on the C# 6 language features, see the Roslyn Codeplex site.

like image 145
Jon Skeet Avatar answered Sep 22 '22 16:09

Jon Skeet