解决方案 1:添加 Type 字段:
添加一个指定对象类型的字段可能是最简单的选择,但您必须能够更改对象才能做到这一点。
public Enum UserType { Teacher, Student, /* possibly other types */ }
public interface ISchoolMember
{
public string Name { get; }
..
public UserType Type { get; }
}
然后,一旦你有了 JSON,你就可以将它解析为 JObject 并读取 Type 字段:
public ISchoolMember Deserialize(string jsonString)
{
var o = JObject.Parse(jsonString);
return (UserType)o["Type"] switch
{
UserType.Teacher => JsonConvert.Deserialize<Teacher>(jsonString),
UserType.Student => JsonConvert.Deserialize<Student>(jsonString),
_ => throw new ArgumentException("...")
};
}
解决方案 2:检查特殊字段。
如果无法添加新字段,则可以检查解析后的 JObject 是否包含仅属于两个对象之一的字段:
public void DeserializeAndDoStuff(string jsonString)
{
var teacherOrStudent = JObject.Parse(jsonString);
if (teacherOrStudent["StudentId"] != null) // it is a student!
{
Student s = teacherOrStudent.ToObject<Student>();
// ... do stuff with the student object
}
else if (teacherOrStudent["TeacherId"] != null) // it is a teacher!
{
Teacher t = teacherOrStudent.ToObject<Teacher>();
// ... do stuff with the teacher object
}
else
{
throw new ArgumentException("The given object is neither a teacher or a student.");
}
}
这两种方法似乎比原始方法更冗长,但有助于摆脱基于异常的编程(这总是不明智的,因为处理异常在资源方面非常昂贵)。
附言
此实现使用 Newtonsoft.Json 库,但我猜其他库也有类似的机制。