我正在为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
绝对不是空的...所以为什么以下线无法识别它?
答案 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;