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.

3
  • "IDE0017 C# Object initialization can be simplified" Commented May 1, 2017 at 17:28
  • R# already gave you the key phrase to look up: "object initializer." Commented May 1, 2017 at 18:06
  • I would just like to point out that the msdn on object initializers makes no mention of using the form without creating a new object. msdn.microsoft.com/en-us/library/bb384062.aspx Commented May 1, 2017 at 20:10

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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.
@JakePadgett It's weird, you don't see it much, but apparently it's been around for a while. 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.