3

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

Community
  • 1
  • 1
eouw0o83hf
  • 9,438
  • 5
  • 53
  • 75
  • 2
    Huh. Nice example. Who'd a thunk that this was possible? I would prefer something more explicit. At some threshold inline initializers just look terrible. This crosses that threshold, IMO. – Keith Payne Aug 20 '13 at 15:25
  • I kind of agree - what is *actually* happening becomes a little less explicit. Additionally, the behavior is constrained to this particular example, as far as I can tell - you can't just initialize properties for an already-constructed `object` outside of some parent initializer. – eouw0o83hf Aug 20 '13 at 15:28
  • Hrmmm, I was going to answer that you need to look at Object initializers, but you already tagged that in the post...however that is what is happening here. Maybe I am misunderstanding the question – Justin Pihony Aug 20 '13 at 15:28
  • Yeah, I looked back over the documentation but can't find any mention of this particular behavior: setting the properties of `Target` without actually setting `Target` itself – eouw0o83hf Aug 20 '13 at 15:29
  • Is there a way to summon Jon Skeet on here? – eouw0o83hf Aug 20 '13 at 15:40
  • It's all in there: http://stackoverflow.com/questions/16794925/nested-object-initializer-syntax – Gaz Aug 20 '13 at 15:47
  • possible duplicate of [Initializer syntax](http://stackoverflow.com/questions/2020143/initializer-syntax) – Stephane Delcroix Oct 16 '13 at 15:00
  • http://stackoverflow.com/questions/16794925/nested-object-initializer-syntax – eouw0o83hf Dec 31 '14 at 00:35

2 Answers2

2

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.

Justin Pihony
  • 66,056
  • 18
  • 147
  • 180
  • Right - it's just really fascinating that there's this little gem of initialization syntax sitting out there that most people seem to be unaware of... – eouw0o83hf Aug 20 '13 at 16:32
0

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.

Nilesh
  • 2,583
  • 5
  • 21
  • 34
  • Yeah - I'm pretty clear on what it's doing, just trying to find some documentation on the nuances of object initialization and what other little tricks I can play with it. Thanks though! – eouw0o83hf Aug 20 '13 at 16:27