如何用初始化器语法为只读属性(如JsonPolymorphismOptions.DerivedTypes)赋值预组装列表?
集合初始化器与只读属性的赋值差异问题
问题重现
以下代码可以正常编译:
public abstract class Base { } public class Foo : Base { } public class Bar : Base { } public static void TestA() { JsonPolymorphismOptions options = new JsonPolymorphismOptions { DerivedTypes = { new JsonDerivedType(typeof(Foo), nameof(Foo)), new JsonDerivedType(typeof(Bar), nameof(Bar)), } }; }
但这段代码编译失败:
public static void TestB() { IList<JsonDerivedType> subtypes = new List<JsonDerivedType>() { new JsonDerivedType(typeof(Foo), nameof(Foo)), new JsonDerivedType(typeof(Bar), nameof(Bar)), }; JsonPolymorphismOptions options = new JsonPolymorphismOptions { DerivedTypes = subtypes }; }
报错信息:
Error CS0200 Property or indexer 'JsonPolymorphismOptions.DerivedTypes' cannot be assigned to -- it is read only
原因解析
核心差异在于两种语法的本质:
- TestA的集合初始化器语法:
DerivedTypes = { ... }并不是给DerivedTypes属性赋值,而是先获取该属性返回的集合实例,再依次调用集合的Add方法添加元素。因为DerivedTypes是只读属性(只有getter),但它返回的是一个可修改的集合(比如实现了IList<T>的可写集合),所以这种操作是合法的。 - TestB的直接赋值语法:
DerivedTypes = subtypes是试图将DerivedTypes属性指向一个新的集合实例,而只读属性不支持重新赋值,因此触发编译错误。
解决方案
要给DerivedTypes添加预组装的列表元素,不需要重新赋值集合,而是将预定义列表中的元素逐个添加到DerivedTypes返回的集合中:
方法1:使用foreach循环添加
public static void TestB() { IList<JsonDerivedType> subtypes = new List<JsonDerivedType>() { new JsonDerivedType(typeof(Foo), nameof(Foo)), new JsonDerivedType(typeof(Bar), nameof(Bar)), }; JsonPolymorphismOptions options = new JsonPolymorphismOptions(); foreach (var derivedType in subtypes) { options.DerivedTypes.Add(derivedType); } }
方法2:使用AddRange(如果集合支持)
如果DerivedTypes返回的集合类型支持AddRange方法(比如List<T>或Collection<T>),可以直接批量添加:
public static void TestB() { IList<JsonDerivedType> subtypes = new List<JsonDerivedType>() { new JsonDerivedType(typeof(Foo), nameof(Foo)), new JsonDerivedType(typeof(Bar), nameof(Bar)), }; JsonPolymorphismOptions options = new JsonPolymorphismOptions(); options.DerivedTypes.AddRange(subtypes); }
内容的提问来源于stack exchange,提问作者Joerg
相关产品推荐
相关产品推荐

