为什么在速记成员初始化的当前上下文中不存在名称?

时间:2017-07-20 10:06:08

标签: c# object-initializers

我正在为st对象使用对象初始值设定项:

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
};

第二个初始化程序行给出错误:

  

当前上下文中不存在名称“ContainedItem”。

     

无效的初始化成员声明符。

并建议在本地范围内的某处声明ContainedItem

现在,当第一行有效时,可以看出ContainedItem实际上是Container的有效属性,而MyContainer.ContainedItem绝对不是空的...所以为什么以下线无法识别它?

4 个答案:

答案 0 :(得分:4)

内联对象初始化的语法已明确指定。你不能只是制造东西并期望编译器理解。语法严格:

{
    Property1 = Value1,
    Property2 = Value2,
    ...
}

c.x不是st的属性。 c是。因此,你不能说c.x = Bar[i].x

来自C#语言规范部分7.6.10.2:

object-initializer:

{ member-initializer-listopt }
 { member-initializer-list , } member-initializer-list:
 member-initializer
 member-initializer-list , member-initializer member-initializer:
 identifier = initializer-value initializer-value:
 expression
 object-or-collection-initializer

答案 1 :(得分:3)

您可以按原样为“子属性”指定值,而不是使用该语法。这是一个完整的例子:

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" }
        };
    }
}

Main中的对象初始值设定项等同于:

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

请注意,这依赖于Container.Item返回一个有效对象而没有在对象初始值设定项中显式初始化 - 在我的示例中就是这种情况,但总是的情况

答案 2 :(得分:1)

您无法在初始化程序的左侧使用表达式,例如c.x。这包括方法调用以及getter / setter:

var s = new S { x.MyMethod() };

在初始化器中唯一能做的就是设置当前类型的属性

来自MSDN

  

对象初始值设定项允许您为任何可访问的字段或值分配值   对象的属性

但是c.x不是st的字段或属性,它甚至不是有效名称。

然而,这会奏效:

var s = new st();
{
    c = new ct()
};
s.c.x = Bar[i].x;

答案 3 :(得分:0)

这是因为您正在尝试在对象初始化器内部进行初始化对象成员而c.x不是对象s的已定义成员。因此说错误。而是尝试在对象初始化程序之外执行它

s.c.x = Bar[i].x;