为什么JSON.NET不反序列化某些类成员?

时间:2017-03-17 17:44:37

标签: c# json.net

说我有一个简单的课程:

[DataContract]
class ClassA
{
    [DataMember]
    public Stopwatch swMember { get; set; }

    [DataMember] 
    public SomeEnum enumMember { get; set; }

    [DataMember]
    public bool boolMember { get; set; }

    [DataMember]
    public Task taskMember { get; set; }
    public ClassA()
    {
        swMember = new Stopwatch();

    }
}

public enum SomeEnum
{
    x,y,z
}

我为A创建一个对象并为其赋值:

ClassA a = new ClassA();
a.swMember.Start();
Thread.Sleep(1000);
a.enumMember = SomeEnum.z;
a.boolMember = true;
a.taskMember = Task.Factory.StartNew(() => "A");

然后我序列化这个对象并将其反序列化为另一个对象:

 ClassA a1 = JsonConvert.DeserializeObject<ClassA>(JsonConvert.SerializeObject(a));

这是实例'a'的序列化版本:

{"swMember":{"IsRunning":true,"Elapsed":"00:00:07.0445661","ElapsedMilliseconds":7044,"ElapsedTicks":19218028},"enumMember":2,"boolMember":true,"taskMember":{"Result":"A","Id":1,"Exception":null,"Status":5,"IsCanceled":false,"IsCompleted":true,"CreationOptions":0,"AsyncState":null,"IsFaulted":false}}

这就是'a1'的实例 Image 1 Image 2 那么为什么反序列化版本会保留像bool值或枚举值这样的简单成员,为什么它会重置像秒表和任务值这样的复杂成员呢?

1 个答案:

答案 0 :(得分:2)

序列化复杂对象时,默认情况下,Json.Net会序列化该对象上的所有公共属性,包括只读对象。例如,在IsRunning类上,您将获得JSON中ElapsedElapsedMillisecondsElapsedTicksIsRunning的属性。所有这些都是只读的。

当您将JSON反序列化为对象时,Json.Net使用默认构造函数(如果可能)构造这些对象的新实例,然后尝试使用公共属性设置器从JSON填充它们。当反序列化器在JSON中找到Elapsed*Stopwatch属性时,它注意到Stopwatch类上的相应属性是只读的,无法设置。所以,它只是跳过它们。因此,如果您检查Task的反序列化实例,它将显示为已重置。实际上,它从未启动过 - 它是一个新实例,与您序列化的原始实例不同。与Stopwatch对象相同的想法。

在实践中,尝试序列化Taskmodels <- lapply(my_list, function(l) { lm(l[[3]] ~ l[[2]], data = l) } ) anova_tabs <- lapply(models, function(m) { anova(m) }) 之类的内容确实很有意义。这些类代表瞬态操作,而不是数据。