【发布时间】:2014-08-28 16:15:56
【问题描述】:
我正在使用 json.net 为 winform 应用程序实现 memento pattern。我正在使用备忘录回滚失败的数据库事务中的对象。我遇到的问题是,在反序列化备忘录时,调用的是 getter 而不是 setter。让我演示一下:
class MyClass
{
public int ID { get; set; }
public string field1 { get; set; }
public string field2 { get; set; }
private List<SomeObject> _someObjects;
public List<SomeObject> SomeObjects
{
get
{
if(_someObjects == null)
{
_someObjects = LoadSomeObjectsFromDB();
}
return _someObjects;
}
set
{
_someObjects = value;
}
}
private List<AnotherObject> _anotherObjects;
public List<AnotherObject> AnotherObjects
{
get
{
if(_anotherObjects == null)
{
_anotherObjects= LoadAnotherObjectsFromDB();
}
return _anotherObjects ;
}
set
{
_anotherObjects = value;
}
}
}
*MyObject、SomeObject 和 AnotherObject 扩展同一个基类 Model
从上面的示例类可以看出,如果 SomeObjects 还没有加载,它会使用Lazy Loading 从数据库中加载它。现在当我序列化这个对象时。
string memento = JsonConvert.SerializeObject(obj);
导致
{
"ID": 1,
"field1": "field 1",
"field2": "field 2",
"SomeObjects": [
{
"ID": 1,
},
{
"ID": 2,
},
{
"ID": 3,
}
],
"AnotherObjects": [
{
"ID": 4,
},
{
"ID": 5,
},
{
"ID": 6,
}
]
}
然后反序列化它。
MyObject obj = JsonConvert.DeserializeObject(memento, typeof(MyObject));
我得到一个由以下 JSON 表示的对象
{
"ID": 1,
"field1": "field 1",
"field2": "field 2",
"SomeObjects": [
{
"ID": 1,
},
{
"ID": 2,
},
{
"ID": 3,
},
{
"ID": 1,
},
{
"ID": 2,
},
{
"ID": 3,
}
],
"AnotherObjects": [
{
"ID": 4,
},
{
"ID": 5,
},
{
"ID": 6,
},
{
"ID": 4,
},
{
"ID": 5,
},
{
"ID": 6,
}
]
}
SomeObjects 和 AnotherObjects Lists 中的项目太多
SomeObjects getter 被调用,这会导致 List 从 DB 初始化,然后将序列化列表附加到它。让我在列表中留下比预期更多的项目。但是如果我删除延迟加载部分
public List<SomeObject> SomeObjects
{
get
{
/*if(_someObjects == null)
{
_someObjects = LoadSomeObjectsFromDB();
}*/
return _someObjects;
}
set
{
_someObjects = value;
}
}
getter 仍然被调用,但返回 null。然后 json.net 调用 setter,value 是一个已经添加了正确数量的元素的列表,而如果 getter 返回一个初始化列表,它会附加到它永远不会调用 ths setter。为什么存在差异,如果列表已经初始化,则调用 getter 并将其附加到。但如果未初始化,则调用 setter 并使用已填充对象的列表对其进行初始化。有没有办法让 json.net 只在通用List 反序列化期间调用设置器?
【问题讨论】:
标签: c# winforms json.net json-deserialization