反序列化使得字段是空列表而不是 null

Posted

技术标签:

【中文标题】反序列化使得字段是空列表而不是 null【英文标题】:Deserializing such that a field is an empty list rather than null 【发布时间】:2012-08-10 09:41:56 【问题描述】:

如果我有这样的课程:

[DataContract(Name = "", Namespace = "")]
public class MyDataObject

    [DataMember(Name = "NeverNull")]
    public IList<int> MyInts  get; set; 

当下面的字符串被反序列化时,有没有办法让 MyInts 字段成为非空的空列表?

string serialized = @"""NeverNull"":null";

MyDataObject myDataObject = JsonConvert.DeserializeObject<MyDataObject>(serialized);

我正在使用 Newtonsoft.Json

我问的原因是我有一个相当复杂的 json 请求要解析,它包含对象列表的嵌套,我想要反序列化代码来创建这些对象,这样我就可以避免大量的空检查:

if (foo.bar != null)

    foreach (var bar in foo.bar)
    
        if (bar.baz != null)
        
            foreach (var baz in bar.baz)
            
                ...

【问题讨论】:

【参考方案1】:

也许添加一个在反序列化结束时检查这个的序列化后回调?

[DataContract(Name = "", Namespace = "")]
public class MyDataObject

    [OnDeserialized]
    public void OnDeserialized(StreamingContext context)
    
        if (MyInts == null) MyInts = new List<int>();
    
    [DataMember(Name = "NeverNull")]
    public IList<int> MyInts  get; set; 

还要注意JsonConvert(不像DataContractSerializer)执行默认构造函数,所以通常你也可以只添加一个默认构造函数:

    public MyDataObject()
    
        MyInts = new List<int>();
    

但是,在这种情况下,explict "NeverNull":null 在反序列化期间将其改回 null,因此我在上面使用了回调。

【讨论】:

【参考方案2】:

IList&lt;int&gt;new int[0]的初始化会帮助你! 它是给我最好结果的解决方案。

【讨论】:

以上是关于反序列化使得字段是空列表而不是 null的主要内容,如果未能解决你的问题,请参考以下文章

C# Xmlserializer 将列表反序列化为 0 而不是 null

当值为“null”时,Jackson 忽略自定义字段反序列化器

杰克逊将单个项目反序列化为列表

反序列化在不同 MailChimp 列表中具有不同名称的合并字段和兴趣

Spring 尝试反序列化为 LinkedHashMap 而不是 POJO

C# xml 反序列化不会将子元素提取到列表中