1. 测试数据结构
public interface IPerson
{
string Name { get; set; }
}
public class Person : IPerson
{
public string Name { get; set; }
public Test Test { get; set; } = new Test();
}
public class Test
{
public string AA { get; set; } = "AA";
public string BB { get; set; } = "BB";
}
public class Student : Person
{
public string Lesson { get; set; }
}
public class Teacher : Person
{
public int Age { get; set; }
}
2. 类图
3. 直接序列化与反序列化
void Main()
{
List<Person> list = new List<UserQuery.Person>();
list.Add(new Person() { Name = "zhangsan" });
list.Add(new Student() { Name = "lisi", Lesson = "123" });
list.Add(new Teacher() { Name = "wangwu", Age = 33 });
var settings = new JsonSerializerSettings
{
Formatting = Newtonsoft.Json.Formatting.Indented,
NullValueHandling = NullValueHandling.Include,
MissingMemberHandling = MissingMemberHandling.Ignore
};
var strJson = Newtonsoft.Json.JsonConvert.SerializeObject(list, settings);
strJson.Dump();
MethodOne(strJson);
}
private void MethodOne(string strJson)
{
var settings = new JsonSerializerSettings
{
Formatting = Newtonsoft.Json.Formatting.Indented,
NullValueHandling = NullValueHandling.Include,
MissingMemberHandling = MissingMemberHandling.Ignore
};
var list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Person>>(strJson, settings);
list.Dump();
}
3.2 序列化结果
[
{
"Name": "zhangsan",
"Test": {
"AA": "AA",
"BB": "BB"
}
},
{
"Lesson": "123",
"Name": "lisi",
"Test": {
"AA": "AA",
"BB": "BB"
}
},
{
"Age": 33,
"Name": "wangwu",
"Test": {
"AA": "AA",
"BB": "BB"
}
}
]
3.2 反序列化结果
由结果可以发现,序列化能够正常的序列化各子类的所有属性,而反序列化的结果仅仅包含每个子类从基类继承的属性,而没有各子类的特定的属性。显然这并不是我们需要的。
4. 分步反序列化
为了执行分布反序列化,需要对原有的数据结构做写修改。需要在序列化时加入一个能够确定该类是啥类的唯一属性,这里使用类的GUID
。修改后如下:
public interface IPerson
{
string Name{get;set;}
string GUID {get;set;}
}
public class Person : IPerson
{
public string Name{get;set;}
public string GUID {get;set;} = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.GUID.ToString();
public Test test{get;set;} = new Test();
}
public class Test
{
public string AA{get;set;} ="AA";
public string BB{get;set;} ="BB";
}
public class Student : Person
{
public string Lesson{get;set;}
public Student()
{
this.GUID = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.GUID.ToString();
}
}
public class Teacher : Person
{
public int Age{get;set;}
public Teacher()
{
this.GUID = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.GUID.ToString();
}
}
void Main()
{
List<Person> list = new List<UserQuery.Person>();
list.Add(new Person() { Name = "zhangsan" });
list.Add(new Student() {Name="lisi", Lesson="123"});
list.Add(new Teacher(){Name="wangwu", Age = 33});
var settings = new JsonSerializerSettings
{
Formatting = Newtonsoft.Json.Formatting.Indented,
NullValueHandling = NullValueHandling.Include,
MissingMemberHandling = MissingMemberHandling.Ignore
};
var strJson = Newtonsoft.Json.JsonConvert.SerializeObject(list, settings);
strJson.Dump();
MethodTwo(strJson);
}
private void MethodTwo(string strJson)
{
Dictionary<string, Type> guids = new Dictionary<string, Type>();
guids.Add(typeof(Person).GUID.ToString(), typeof(Person));
guids.Add(typeof(Student).GUID.ToString(), typeof(Student));
guids.Add(typeof(Teacher).GUID.ToString(), typeof(Teacher));
List<Person> list = new List<UserQuery.Person>();
using (StringReader sr = new StringReader(strJson))
{
JsonTextReader jtr = new JsonTextReader(sr);
while (jtr.Read())
{
if (jtr.TokenType == JsonToken.StartObject)
{
JObject obj = JObject.Load(jtr);
obj.ToString().Dump();
foreach (var element in guids.Keys)
{
if (obj.Property("GUID").Value.ToString() == element)
{
list.Add((Person)Newtonsoft.Json.JsonConvert.DeserializeObject(obj.ToString(), guids[element]));
}
}
}
}
}
list.Dump();
}
4.1 序列化结果
[
{
"Name": "zhangsan",
"GUID": "fe88be23-6d26-3315-9438-d788614a229d",
"test": {
"AA": "AA",
"BB": "BB"
}
},
{
"Lesson": "123",
"Name": "lisi",
"GUID": "8cd8bae9-6962-3e9d-81db-3e8c534158e7",
"test": {
"AA": "AA",
"BB": "BB"
}
},
{
"Age": 33,
"Name": "wangwu",
"GUID": "506f3728-33f8-3c37-ad2c-1b49247c4498",
"test": {
"AA": "AA",
"BB": "BB"
}
}
]
4.2 反序列化结果
由结果可见,正确得到了每个子类的特有属性