假设我有一个像这样的类的实例,我想序列化为JSON:
public class MyClass
{
public MyClass() { }
private List<string> texts;
public List<string> Texts
{
get
{
return new List<string> { "You got me!" };
}
set
{
texts = value;
Console.WriteLine("Setting property!");
}
}
}
我想确保在反序列化期间调用“文本”的set访问器,即确保MyClass中的私有属性“texts”被设置。但是,如果我运行一个小测试用例:
public void TestMyClass()
{
var myClass = new MyClass();
var jsonBefore = JsonConvert.SerializeObject(myClass);
var jsonAfter = JsonConvert.DeserializeObject<MyClass>(jsonBefore);
}
set方法永远不会被调用,即反序列化后私有“texts”为null。如何确保在反序列化期间调用公共“文本”中的set访问器?
答案 0 :(得分:1)
第一个原因是因为你使用的newtonsoft json序列化器与内置的.net one完全不同。
var json = new JavaScriptSerializer().Serialize(myClass);
var obj = new JavaScriptSerializer().Deserialize<MyClass>(json);
此代码可以正常运行。
第二个原因是你的get属性以及newtonsoft json序列化程序如何处理它,你有默认的列表创建(最好把它放到构造函数中,因为它现在没有任何意义)
如果您仍想使用现在实现的get,请使用JsonSerializerSettings.ObjectCreationHandling设置来自定义对象创建,
var jsonBefore = JsonConvert.SerializeObject(myClass);
var jsonAfter = JsonConvert.DeserializeObject<MyClass>(jsonBefore, new JsonSerializerSettings
{
ObjectCreationHandling = ObjectCreationHandling.Replace
});
答案 1 :(得分:1)
如果您不想在Texts
属性中设置null,则可以为其设置默认值。
与private List<string> texts = new List<string>(){ "Default Value" };
而不是
get
{
return new List<string> { "You got me!" };
}
你应该使用
get
{
return texts;
}
答案 2 :(得分:1)
序列化是将数据结构或对象状态转换为可以存储的格式(在我们的例子中是json)的过程。
对象状态由字段值组成,所有方法或其他行为逻辑都被忽略。
属性基本上是与支持字段一起使用的方法,因此它们不用于序列化/反序列化,因为它们不代表对象的状态。
在我们的案例中,字段texts
使用反射进行序列化。然后它被直接反序列化,并且序列化程序可能甚至不知道该属性存在。