C#仅含Get实现属性的初始化特性及System.Text.Json Converters疑问
为什么C#中仅含getter的属性可以在对象初始化器中添加元素?
你观察到的这种行为依赖于C#集合初始化器特性,核心原理并不是给Converters属性赋值,而是操作该属性返回的集合实例本身:
集合初始化器的语法逻辑
对象初始化器里的Converters = { new DateTimeOffsetJsonConverter() }并不是尝试给Converters属性设置新值(它只有getter,确实无法赋值),而是一种语法糖:编译器会先调用serializeOptions.Converters获取集合实例,再自动调用该集合的Add方法,把括号里的元素添加进去。Converters属性的内部实现JsonSerializerOptions的Converters属性虽然对外只暴露getter,但它内部在类的构造函数中已经初始化了一个可变的集合实例(比如List<JsonConverter>)。当你通过属性获取这个集合时,拿到的是可以修改的实例,所以调用Add方法(集合初始化器的底层操作)就能成功添加元素。
举个简化的等效代码,帮你理解编译器做了什么:
var serializeOptions = new JsonSerializerOptions(); serializeOptions.WriteIndented = true; // 集合初始化器的等效手动操作 serializeOptions.Converters.Add(new DateTimeOffsetJsonConverter());
- 关键前提
这种写法能生效的必要条件是:属性返回的集合类型必须实现了支持Add方法的接口(比如IList<T>、ICollection<T>),并且集合实例本身是可变的。如果返回的是不可变集合(比如ImmutableList<T>),这种写法就会编译失败,因为不可变集合没有能修改原实例的Add方法。
内容的提问来源于stack exchange,提问作者Trey Mack
相关产品推荐
相关产品推荐

