为什么集合初始值设定项仅适用于 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 中的引用,它已经被字段初始化器初始化。
这对我来说是非常不可预测的代码结果。
没想到这段代码会产生这样的结果
所以,我读了 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 中的引用,它已经被字段初始化器初始化。