在填充现有对象时添加项目之前清除集合

我有一个对象,它有几个使用public getter但私有setter定义的集合属性。在这种情况下, JsonConvert.PopulateObject将反序列化的项添加到这些集合中,使现有项保持不变。

在反序列化之前清除此类成员集合时,我需要一种行为。

我尝试在标有[OnDeserializing]属性的方法中手动清除集合。

该方法的问题在于,即使JSON字符串中不存在collection属性,它仍将清除集合。

当只有那些集合被清除时,我需要一种方法,这些集合实际上是在JSON字符串中定义的。 那些未定义的应该保持不变。

谢谢

好的,所以在一些Json.NET源代码之后,我通过从DefaultContractResolverinheritance自定义合约解析器找到了以下解决方案。

我需要覆盖数组合同创建以添加反序列化回调。 此时回调接收具体的集合实例,因此我们可以操作它(在这种情况下清除它)。

只要我能确定,使用它是安全的,但随时可以警告这种方法的任何缺点。

注意:我是唯一一个认为这应该是默认行为的人吗?

 public class CollectionClearingContractResolver : DefaultContractResolver { protected override JsonArrayContract CreateArrayContract(Type objectType) { var c = base.CreateArrayContract(objectType); c.OnDeserializingCallbacks.Add((obj, streamingContext) => { var list = obj as IList; if (list != null && !list.IsReadOnly) list.Clear(); }); return c; } } ... public class Test { public List List { get; private set; } public Test() { List = new List(); } } ... var myObj = new Test(); myObj.List.AddRange(new[] {1,2,3}); var listReference = myObj.List; JsonConvert.PopulateObject("{ List: [4, 5, 6] }", myObj, new JsonSerializerSettings { ContractResolver = new CollectionClearingContractResolver(), }); myObj.List.ShouldEqual(listReference); // didn't recreate list myObj.List.Count.ShouldEqual(3); myObj.List.SequenceEqual(new[] { 4, 5, 6}).ShouldBeTrue();