Решение 1 : Добавить Тип поле:
Добавление поля, в котором указан тип объекта, вероятно, самый простой выбор, но вы должны иметь возможность изменить объекты, чтобы сделать это.
public Enum UserType { Teacher, Student, /* possibly other types */ }
public interface ISchoolMember
{
public string Name { get; }
..
public UserType Type { get; }
}
Затем, получив JSON, вы можете проанализировать его в JObject и прочитать поле Тип:
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.");
}
}
Эти два метода кажутся более многословными, чем исходный, но помогают отойти от программирования на основе исключений (это всегда не учитывается, поскольку обработка исключений очень затратна с точки зрения ресурсов) .
ps
эта реализация использует библиотеку Newtonsoft. Json, но я предполагаю, что другие библиотеки имеют аналогичные механизмы.