说我有一个简单的课程:
[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值或枚举值这样的简单成员,为什么它会重置像秒表和任务值这样的复杂成员呢?
答案 0 :(得分:2)
序列化复杂对象时,默认情况下,Json.Net会序列化该对象上的所有公共属性,包括只读对象。例如,在IsRunning
类上,您将获得JSON中Elapsed
,ElapsedMilliseconds
,ElapsedTicks
和IsRunning
的属性。所有这些都是只读的。
当您将JSON反序列化为对象时,Json.Net使用默认构造函数(如果可能)构造这些对象的新实例,然后尝试使用公共属性设置器从JSON填充它们。当反序列化器在JSON中找到Elapsed*
和Stopwatch
属性时,它注意到Stopwatch
类上的相应属性是只读的,无法设置。所以,它只是跳过它们。因此,如果您检查Task
的反序列化实例,它将显示为已重置。实际上,它从未启动过 - 它是一个新实例,与您序列化的原始实例不同。与Stopwatch
对象相同的想法。
在实践中,尝试序列化Task
和models <- lapply(my_list, function(l) { lm(l[[3]] ~ l[[2]], data = l) } )
anova_tabs <- lapply(models, function(m) { anova(m) })
之类的内容确实很有意义。这些类代表瞬态操作,而不是数据。