Object Initializers, Non-Public Children, and Nested Initialization

770 Views Asked by At

I was looking through my codebase and found a line of code that R# had helpfully refactored for me. Here's a representative sample:

public class A
{
    public B Target { get; private set; }
    public object E { get; set; }

    public A()
    {
        Target = new B();
    }
}

public class B
{
    public object C { get; set; }
    public object D { get; set; }
}

public static class Test
{
    static A LocalA;
    static void Initialize()
    {
        LocalA = new A
        {
            E = "obviously this should be settable",
            Target =
            {
                C = "Whoah, I can set children properties",
                D = "without actually new-ing up the child object?!"
            }
        };
    }
}

Essentially, initialization syntax allows for setting a child object's public properties without actually performing the constructor call (obviously if I pull the Target constructor call from the constructor of A, the whole initialization fails due to a null reference.

I've searched for this, but it's difficult to put into Google-able terms. So, my question is: (a) what is this called exactly, and (b) where can I find some more information in C# documentation about it?


Edit

Looks like someone else has asked this with similar lack of documentation found: Nested object initializer syntax

2

There are 2 best solutions below

1
On

There is nothing concrete in the documentation that I see on this topic of Object Initializers, but I did decompile the code, and here is what it actually looks like once decompiled:

        A a = new A();
        a.E = "obviously this should be settable";
        a.Target.C = "Whoah, I can set children properties";
        a.Target.D = "without actually new-ing up the child object?!";
        Test.LocalA = a;

A known fact on Object Initializers is that they always run the constructor first. So, that makes the above code work. If you remove the initialization of Target in the constructor of A you will get an exception when the property initializers are tried since the object was never instantiated.

1
On

This might not be the answer and I agree its really difficult to put this into a language that google understands

In this case you are assigning values to C and D which are public properties of Target object

 LocalA.Target.C = "Whoah, I can set children properties";
 LocalA.Target.D = "without actually new-ing up the child object?! Nope I dont think so:)!"

You are not actually initializing a new B() as the Target setter is Private. This is obviously going to fail if B is not initialized.