为什么集合初始值设定项仅适用于 getter-属性?

Why does collection initializer work with getter-only property?

这对我来说是非常不可预测的代码结果。

没想到这段代码会产生这样的结果

所以,我读了 Jeffrey Richter 的书 (clr ia c#) 并且有一个包含此代码的示例。

internal class ClassRoom
{
    private List<String> _students = new List<string>();
    public List<String> Students { get { return _students; } }
}

ClassRoom classRoom = new ClassRoom
{
    Students = {"Mike", "Johny", "Vlad", "Stas"}
};

foreach (var some in classRoom.Students)
{
    Console.WriteLine(some);
}

而且,正如你们中的一些人所建议的那样,我们可以在控制台中看到四个名字。 所以,我的问题是:

我们如何获得我们的名字,如果他们要分别进入 Students 和 _students,因为不存在 Students setter。

__________EDIT_1_______________

我看了你的回答,谢谢你。

但是,你知道,这是一种误会...... 实在想不通

当我初始化 Students 时,我初始化 _students ?

同样重要的是,当我从 IEnumerable(some) 获取变量时, 我从 Students 获取变量? 我觉得不是。

我不明白,我到底在哪里分配变量(初始化)_students 集合?

谢谢你帮我弄清楚!

通过说 Students = {"Mike", "Johny", "Vlad", "Stas"} 它正在做的是

属性 Students returns 底层 List<String> _students 实例,并且您正在使用集合初始值设定项添加字符串文字。

So, when I iterate through Students, am I iterate through the _students ?

从技术上讲是的,您的 _students 是一个 private 变量,而 Students 属性 是该私有字段的包装器,以便外部消费者可以访问该列表。

因此,当您说 Students = ... 时,您实际上是在设置或初始化私有字段,因为访问 Students 会返回 List<string> 实例。

_students 字段在构造时在内部分配一次,缺少 public setter 阻止它从外部设置为不同的列表实例。 ClassRoom 的对象初始化器实际上并没有设置 Students 集合 属性,而是简单地利用集合初始化器语法将初始项 添加 Students。 ..

ClassRoom classRoom = new ClassRoom
{
    Students = { "Mike", "Johny", "Vlad", "Stas" }
};

上面的内容与下面的内容类似,但不完全相同,因为对象初始化程序版本在填充集合后才执行对 classRoom 的赋值。

ClassRoom classRoom = new ClassRoom();
classRoom.Students.Add("Mike");
classRoom.Students.Add("Johny");
classRoom.Students.Add("Vlad");
classRoom.Students.Add("Stas");

相反,请注意,由于缺少 public setter,以下内容将产生编译器错误,因此访问确实如预期的那样受到限制...

ClassRoom classRoom = new ClassRoom
{
    Students = new List<string> { "Mike", "Johny", "Vlad", "Stas" }
}

这些其他答案几乎正确。让我们仔细研究一下,真正搞定它。

Why does a collection initializer work with a getter-only property?

因为属性值没有改变。 属性 引用的集合的内容是更改的内容。

将 属性 想象成一个桶。您无法更改 属性 指的是哪个存储桶,但可以更改存储桶的内容。

How do we get our names, if they are going to get in Students and respectively in _students, that were not assigned because of nonexistence of Students setter.

学生 属性 根本没有分配。怎么会这样?它没有setter。

这些名字已添加到学生 getter 引用的集合中。

When I Initialize Students, I initialize _students ?

没有。 _students的初始化是给_students赋值的那一行。

集合初始值设定项将值添加到现有集合。变量 _students 已经初始化。

when I take variable from IEnumerable(some), I am take variable from Students ?

你不会从任何东西中获取变量。您取 。变量不是值;变量 包含 值。不要将存储与存储的值混淆。

I can't understand, WHERE exactly I assign variables(INITALIZE) _students collections ?

_students 变量在初始化_students 的行中被初始化。集合的 contents 在包含内容的行中初始化。

也许这有助于按照发生的顺序列出所有发生的事情:

  • 创建了一个新的 Classroom 对象; _students 字段为空;生成对该对象的引用。
  • 创建了一个新的空列表;对该列表的引用被复制到新创建的 Classroom 对象的 _students 字段中。
  • 学生 getter 在对新 Classroom 对象的引用上被调用。它 returns _students 的内容,这是对空列表的引用。
  • 四项已添加到该列表
  • Classroom 对象的引用被复制到 classroom 变量。

或者,在代码中,这相当于:

c = create a Classroom
c._students = null
l1 = create a List<string>
c._students = l1
l2 = c.Students -- which returns c._students
l2.Add("...")  -- four times
classRoom = c

看,从来没有 setter 的学生打过电话。没有必要。它所做的只是获取包含在_students 中的引用,它已经被字段初始化器初始化。