C# 嵌套对象初始化器似乎无效,但已编译

C# 嵌套对象初始化器似乎无效,但已编译,c#,initializer,C#,Initializer,如果我有以下没有setter或backing字段的属性 公共列表TestProperty=>新列表{“一”、“二”}; 并尝试在对象初始化器中使用 TestProperty=新列表{“三”,“四”} 我得到了预期的错误: [CS0200] Property or indexer 'X.TestProperty' cannot be assigned to -- it is read only 但是,如果我尝试在对象初始化器中使用 TestProperty={“三”,“四”} 一切都编译得

如果我有以下没有setter或backing字段的属性

公共列表TestProperty=>新列表{“一”、“二”};
并尝试在对象初始化器中使用

TestProperty=新列表{“三”,“四”}
我得到了预期的错误:

[CS0200] Property or indexer 'X.TestProperty' cannot be assigned to -- it is read only
但是,如果我尝试在对象初始化器中使用

TestProperty={“三”,“四”}
一切都编译得很好,但属性仍然返回
newlist{“one”,“two”}

@jon skeet在回答时解释说,第二种形式是嵌套对象初始化器,但我仍然不确定上面的(毫无帮助的)编译的原因,以及是否可以停止编译,并从对象初始化器中的IDE自动完成(ReSharper)中删除属性?这只会让我的代码的用户感到沮丧


编辑:请注意,我不想初始化此属性,我关心的是编译器允许出现类似初始化的情况。

假设您有以下情况:

public class X 
{
    public List<string> TestProperty => new List<string> {"one", "two"};
}
这将大致归结为:

var x = new X();
var list = x.TestProperty; // remember, this is a NEW list
list.Add("a");
list.Add("b");
因此,当您打印(或在调试器中查看)
x.TestProperty
时,这是一个全新的列表,因此您添加的值实际上被忽略

为什么这种语法有效?因为该特性的设计使您通常在构造函数中生成一个空列表,而
Add
调用将添加到该列表中。在这种情况下,您只需决定放弃这些值,因为您可以使用支持字段而不是返回新实例



@madreflection通过调用
x.TestProperty
正确地指出,
Add
的每次调用都会在调用
x.TestProperty
之后完成,因此“a”和“b”将在两个不同的列表中结束。

好吧,
TestProperty
确实会返回一个初始化的
列表,这样您就可以安全地向其中添加数据。数据未分配给
TestProperty
只是您的决定。请注意
x.TestProperty==x.TestProperty
将给您一个惊喜。创建一个新的收藏通常应该是一种方法,而不是一种属性。除此之外,拥有类似于这个问题的东西对于公众来说是一个糟糕的选择API@CamiloTerevinto“property is initialized”(属性已初始化)通常意味着“有一个值分配给属性一次,并且该值保持不变(直到新的分配)”,您使用它的时候不太常见,“属性总是返回非null值”…我完全理解这个属性是一个没有setter的计算属性。我试图理解为什么在对象初始化器中允许使用语法,以及它在做什么……我会接受这一点,但如果将此语法“添加”到(在本例中是计算的)值中,而不是“设置”它,可能会有所帮助。因此没有二传手不是问题。谢谢大家的帮助,谢谢!
var x = new X();
var list = x.TestProperty; // remember, this is a NEW list
list.Add("a");
list.Add("b");