为何可对只读属性使用初始化器语法?Manager类实例化疑问
为什么无set访问器的集合属性能用初始化器,而字符串属性不行?
这是个非常典型的C#语法细节问题,我来给你掰明白背后的逻辑:
首先看你遇到的两种情况的本质区别:
1. Name = "Dave" 报错的原因
这行代码是直接给Name属性赋值,因为Name只定义了get访问器,没有set,编译器会直接阻止这种试图修改属性值的操作,这完全符合你的预期。
2. ReportingEmployeesIds = {2345, 432, 521} 不报错的原因
这行代码看起来像是给属性赋值,但实际上是C#的集合初始化器语法糖——它根本没有尝试修改ReportingEmployeesIds属性的值,而是在调用属性的get方法获取集合实例后,调用集合的Add方法逐个添加元素。
编译器会把这段代码转换成等价的写法:
Manager m = new Manager(); m.ReportingEmployeesIds.Add(2345); m.ReportingEmployeesIds.Add(432); m.ReportingEmployeesIds.Add(521);
你看,这里只是通过get访问器拿到了_reportingEmployeesIds这个集合对象,然后对它的内容进行修改,并没有改变属性本身指向的集合实例。只要你的Manager类在构造函数里已经初始化了_reportingEmployeesIds(比如_reportingEmployeesIds = new List<int>();),这段代码运行时就正常工作;如果没初始化,运行时会抛出NullReferenceException,但编译时编译器不会检查这一点——它只需要确认属性返回的类型有Add方法(List<int>显然满足),就允许这种写法。
关键总结
- 当你写
Property = 值时,是在尝试设置属性的值,必须要有set访问器; - 当你写
Property = { 元素1, 元素2 }时,是在调用属性返回集合的Add方法,只需要属性能通过get返回一个集合实例,不需要set访问器。
内容的提问来源于stack exchange,提问作者Rachel
相关产品推荐
相关产品推荐

