现有的填充对象时加入项目前清除集合 [英] Clear collections before adding items when populating existing objects

查看:102
本文介绍了现有的填充对象时加入项目前清除集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有公共的getter但私人setter方法​​定义了多个集合属性,在这种情况下 JsonConvert.PopulateObject 添加反序列化项目这些集合保留现有项目的对象不变。

I have an object which has several collection properties defined with public getter but private setter, In this case JsonConvert.PopulateObject adds the deserialized items to these collections leaving the existing items untouched.

我需要在这样的成员集合得到反序列化前清零行为。

I need a behavior when such member collections get cleared before deserialization.

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

I tried to manually clear the collections in a method marked with the [OnDeserializing] attribute.

使用这种方法的问题是,它会尚清集合即使集合属性不JSON字符串存在。

The problem with that approach is that it will still clear the collections even if the collection property does not exist in the JSON string.

我需要这是在JSON字符串实际上定义时,只有那些藏品清关的方式。那些不确定应保持不变。

I need a way when only those collections get cleared which are actually defined in the JSON string. Those which are undefined should be kept untouched.

感谢

推荐答案

好了,所以一些一趟Json.NET源后,我从 DefaultContractResolver 继承自定义的合同解析器发现了以下解决方案。

Okay, so after some trip to Json.NET sources I found the following solution by inheriting a custom contract resolver from DefaultContractResolver.

我要重写数组合同创建添加一个反序列化回调。此时的回调收到具体的集合实例,这样我们就可以操纵它(在这种情况下,将其清除)。

I needed to override the array contract creation to add a deserialization callback. At this point the callback receives the concrete collection instance, so we can manipulate it (in this case clear it).

只要我能确定,它是安全的。使用,但随时提醒这个方法的任何缺点

As long as I can determine, it is safe to use, but feel free to warn about any drawbacks of this method.

注:我是唯一一个谁认为这也许应该是默认的行为?

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

这篇关于现有的填充对象时加入项目前清除集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆