Why doesn't name exist in the current context of shorthand member initialisation?

I am using an object initializer for a st object:

public class Container 
{
    public Container () { ContainedItem = new Item; }
    public Item ContainedItem { get; set; }
}

public class Item
{
    public string Value { get; set; }
}

var MyContainer = new Container()
{
    // I want to populate the the property Value of the property Item
    // with the second line rather than the first
    ContainedItem = new Item() { Value = FooString }, // This works
    ContainedItem.Value = FooString  // This assigns to the same member but does not work
};

The second initializer line gives the error:

The name 'ContainedItem' does not exist in the current context.

Invalid initializer member declarator.

and suggests declaring ContainedItem somewhere in local scope.

Now as the first line works it can be seen that ContainedItem is in fact a valid property of Container and that MyContainer.ContainedItem is definitely not null... so why does the following line fail to recognise it?

Jon Skeet
people
quotationmark

You can assign values to "sub-properties" as it were, just not with that syntax. Here's a complete example:

using System;

public class Container
{
    public Item Item { get; set; } = new Item();
}

public class Item
{
    public string Value { get; set; }
}

class Test
{
    static void Main(string[] args)
    {
        var container = new Container
        {
            Item = { Value = "hello" }
        };
    }
}

The object initializer in Main is equivalent to:

var tmp = new Container();
tmp.Item.Value = "hello";
var container = tmp;

Note that this relies on Container.Item returning a valid object without it having been explicitly initialized in the object initializer - which is the case in my example, but isn't always the case.

people

See more on this question at Stackoverflow