5

For this class setup.

public class X
{
    public Y YInstance;

    public X()
    {
        YInstance = new Y();
    }
}

public class Y
{
    public long Z;
}

I had this code.

var x = new X();
x.YInstance.Z = 1;

Resharper had a hint to use object initializer which transformed my code to this.

var x = new X { YInstance = { Z = 1 } };

I'm familiar with normal object initialization using the brackets to fill out properties but I'm not sure what this is doing. Looking at the IL it doesn't appear to be setting YInstance with a new anonymous class which was my first guess. That would also not be the same functionality as before which would weird for Resharper to suggest.

I'm just looking for a language feature keyword to look up or a simple explanation.

1 Answers1

8

Syntax is arbitrary, strictly speaking, but in my view the way to think about it is that YInstance = { Z = 1 } has no new keyword, so it's not calling any constructors. However, the initializer part of the syntax is present, so it's merely applying the initializer to the properties of a (hopefully!) existing YInstance. YInstance exists in your case because you created it in your X constructor. Here's what would happen if you didn't.

Instead of "Set YInstance to this thing", it's "Set the properties of YInstance to those things".

= { ... } in this case means to apply that initializer to the existing value of a property.

Indicating that with = between the property name and the initializer braces may not seem ideally intuitive at first, but it is what it is and like any syntax, you learn to recognize it soon enough. You can do the same to initialize the items of collections that have already been created:

public class C {
    public List<int> Items { get; } = new List<int>();
}

...

//  This can't be assigning to Items, because it's read-only
var c = new C { Items = { 0, 1, 2 } };

One of the C# team members (if you mention his name, he will appear) once kindly took the time to comment on an answer to a question about the list initializer syntax. They kicked it around a lot, but this was the best option they came up with. There are a lot of considerations when it comes to adding syntax to a mature language. They lose a lot of sleep over making it as clear as possible to the programmer, but at the same time it has to be unambiguous to the compiler, it can't break existing code, etc. "Syntax is arbitrary" doesn't mean that the C# team makes arbitrary decisions.

I can't say why Resharper would object to your taking arms against a sea of curly braces. I like your original version better.

Community
  • 1
  • 1
  • Thank you for breaking that down for me! My main problem was I didn't know you could apply {...} to things that have already been created. I've only used it for initial creation I guess. – Jake Padgett May 01 '17 at 18:39
  • 1
    @JakePadgett It's weird, you don't see it much, but [apparently it's been around for a while](http://stackoverflow.com/a/32897735/424129). If you go to project Properties | Build | Advanced..., it works with C#3.0, but not ISO-1 or ISO-2. So it's been around as long as `var`. But I can't find any documentation on it. – 15ee8f99-57ff-4f92-890c-b56153 May 01 '17 at 18:49