3

Example:

class Foo
{
    public Bar Bar { get; set; }
}

class Bar
{
    public string Name { get; set; }
}

...
{
    var foo = new Foo
    {
        Bar = { Name = "abc" } // run-time error
    };
}

Why does C# allow that kind of assignment? IMO, it makes no sense but easier to cause bugs.

Hoang Hiep
  • 2,242
  • 5
  • 13
  • 17
  • 1
    Because anonymous objects are not same as named objects. You can change the type to `object Bar` and see... – Afzaal Ahmad Zeeshan Jan 12 '17 at 16:40
  • 3
    @Afzaal Ahmad Zeeshan: That sounds like a reason for the code to generate a compile-time error. Yet it does not. That's what the question is asking. – BoltClock Jan 12 '17 at 16:41
  • You need to say `Bar = new Bar { Name = "abc" }`, or in `Foo` say `public Bar Bar {get; set;} = new Bar();` – Wagner DosAnjos Jan 12 '17 at 16:43
  • 6
    What you have is an object initializer, not an anonymous object. – Pieter Witvoet Jan 12 '17 at 16:46
  • 1
    Related: [Property initialization does not call set for List](http://stackoverflow.com/questions/37873193/property-initialization-does-not-call-set-for-listt) (which describes collection initializers, but is the same in principle) – BoltClock Jan 12 '17 at 16:47
  • You code uses no anonymous objects anywhere. You're just calling an object initializer when initializing an object. – Servy Jan 12 '17 at 16:47
  • @PieterWitvoet Thanks. I see it now. – Hoang Hiep Jan 12 '17 at 16:48

2 Answers2

7

This is made possible because it would not cause a run-time error if the object had already been instantiated.

class Foo
{
    public Bar Bar { get; set; } = new Bar();
}

{
    var foo = new Foo
    {
        Bar = { Name = "abc" } // no error
    };
}
Matt Rowland
  • 4,575
  • 4
  • 25
  • 34
  • You mean to say "instantiated". Evidently the new expression is the one trying to initialize the Bar instance. It just requires an instance to be there to begin with, regardless of whether it's been initialized by the author's definition. – BoltClock Jan 12 '17 at 16:44
4

This is actually not an anonymous object, but rather the use of object initializer syntax.

{
    var foo = new Foo
    {
        Bar = { Name = "abc" } // run-time error
    };
}

The above snippet is actually the same as saying the following:

{
    var foo = new Foo();
    foo.Bar = new Bar { Name = "abc" }; // Fine, obviouslly
    foo.Bar = { Name = "abc" }; // compile error
}

The object name becomes redundant as it is already known with the use of the object initializer syntax.

David Pine
  • 23,787
  • 10
  • 79
  • 107