12

What is going on with this C# code? I'm not even sure why it compiles. Specifically, what's going on where it's setting Class1Prop attempting to use the object initializer syntax? It seems like invalid syntax but it compiles and produces a null reference error at runtime.

void Main()
{    
    var foo = new Class1
    {
        Class1Prop = 
        {
            Class2Prop = "one"
        }
    };
}

public class Class1
{
    public Class2 Class1Prop { get; set; }
}

public class Class2
{
    public string Class2Prop { get; set; }
}
3
  • 1
    My guess is that is has to do with type inference...but I can't back that up so I'm just going to anxiously await an answer :) Commented Oct 24, 2018 at 20:10
  • 1
    It compiles because it is valid syntax. Only the first object initializer needs to follow a new but nested ones don't. It will work properly if you initialize Class1Prop in a constructor (in Class1). All Class2Prop = "one" does is set the value of the property. Commented Oct 24, 2018 at 20:11
  • Can you explain why you think it should not compile, and why you think this valid syntax is invalid? Which line of the specification or documentation led you to believe that this was invalid? That line should be fixed, since apparently it is misleading. Commented Oct 24, 2018 at 20:28

1 Answer 1

13

This is allowed by object initializer syntax in the C# specification, where it is called a nested object initializer. It is equivalent to:

var _foo = new Class1();
_foo.Class1Prop.Class2Prop = "one"
var foo = _foo;

It should be a little more obvious why this throws a null reference exception. Class1Prop was never initialized in the constructor of Class1.

The benefit of this syntax is that the caller can use the convenient object initializer syntax even when the properties are getter-only to set mutable properties on nested objects. For example, if Class1Prop was a getter-only property the example is still valid.

Note that there is an inaccessible temporary variable created to prevent the access of a field or array slot before the full initialization has run.

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

Comments

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.