这对我来说是非常不可预测的代码结果。
我没想到这段代码会产生这样的结果。
所以,我读了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,那些因为学生不存在而没有被分配。
__________ EDIT_1 _______________
我读了你的答案,谢谢你们。
但是,你知道,这是一种误解...... 我真的无法弄明白。
初始化学生时,我会初始化 _students ?
当我从IEnumerable( some )中获取变量时,重要的是, 我从学生变量? 我想不是。
我无法理解,究竟我在哪里指定变量(INITALIZE) _students 集合?
感谢您帮助我弄明白!
答案 0 :(得分:1)
_students
字段在构建时内部分配一次,缺少公共setter会阻止它从外部设置为不同的列表实例。 ClassRoom的对象初始值设定项实际上并未设置Students
集合属性,而是简单地利用集合初始值设定项语法将添加初始项目添加到Students
... < / p>
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");
相反,请注意,由于缺少公共setter,以下会产生编译器错误,因此访问确实受到了预期的限制......
ClassRoom classRoom = new ClassRoom
{
Students = new List<string> { "Mike", "Johny", "Vlad", "Stas" }
}
答案 1 :(得分:1)
这些其他答案几乎正确。让我们来看看它实际上是否正常。
为什么集合初始值设定项使用仅限getter的属性?
因为属性值未更改。属性引用的集合的内容是更改的内容。
将财产视为一个桶。您无法更改属性引用的存储桶,但您可以更改存储桶的内容。
我们如何获得我们的名字,如果他们要进入学生和_students,那些因为学生不存在而没有被分配。
学生财产从未被分配。怎么会这样?它没有二传手。
这些名字被添加到学生获取者所引用的集合中。
当我初始化学生时,我初始化_students?
没有。 _students的初始化是为_students赋值的行。
集合初始值设定项将值添加到现有集合。变量_students已经初始化。
当我从IEnumerable(某些)获取变量时,我从学生那里获取变量?
你不能从任何东西中获取变量。你拿值。变量不是值;变量包含值。不要将存储与存储的值混淆。
我无法理解,究竟我在哪里分配变量(INITALIZE)_students集合?
_students变量在初始化_students的行中初始化。集合的内容在具有内容的行中初始化。
也许这将有助于按照发生的顺序列出发生的所有事情:
或者,在代码中,这相当于:
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
看,从来没有一个学生叫做。没有必要。它所做的就是获取_students中包含的引用,该引用已经由字段初始化程序初始化。
答案 2 :(得分:0)
说Students = {"Mike", "Johny", "Vlad", "Stas"}
正在做什么
property Students
返回基础List<String> _students
实例,并且您正在使用集合初始值设定项添加字符串文字。
所以,当我遍历学生时,我会迭代学生 _students?
从技术上讲,您的_students
是private
变量,Students
属性是该私有字段的包装,可以将该列表授予外部消费者。
因此,当您说Students = ...
实际上是设置或初始化私有字段时,因为访问Students
会让您返回List<string>
个实例。