【问题标题】:Clear collections before adding items when populating existing objects在填充现有对象时添加项目之前清除集合
【发布时间】:2016-02-18 13:33:16
【问题描述】:

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

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

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

这种方法的问题在于,即使 JSON 字符串中不存在集合属性,它仍然会清除集合。

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

谢谢

【问题讨论】:

  • 您是否尝试将ObjectCreationHandling 设置为Replace?请参阅文档中的Serialization Settings
  • 否,因为据我了解,这意味着它替换了集合,而不是项目。它会创建一个新的列表实例,这不是我想要的(这就是为什么 setter 是私有的,任何人都不应该因为数据绑定等原因弄乱列表实例)。

标签: c# json json.net


【解决方案1】:

好的,所以在访问 Json.NET 资源之后,我通过从 DefaultContractResolver 继承自定义合约解析器找到了以下解决方案。

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

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

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

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<int> List { get; private set; }
    public Test() {
        List = new List<int>();
    }
}  

...

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();

【讨论】:

  • 我会在清除它之前添加一个检查以查看 obj 是否是一个数组,因为数组是只读的。或者查看IList.IsReadOnly
  • 我同意你的观点,我认为这应该是默认行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多