Допустим, у меня есть небольшой фрагмент json:
{
"Type": "Bar",
"BarOnly": "This is a string readable when deserialized to the Bar class only, as declared in my type key"
}
У меня также есть три класса:
public class Base
{
public enum SampleEnum
{
Bar,
Baz,
}
public SampleEnum Type
{
get;
set;
}
}
public class Bar : Base
{
public string BarOnly
{
get;
set;
}
}
public class Baz : Base
{
public string BazOnly
{
get;
set;
}
}
На основе свойства Type во фрагменте json Я хотел бы, чтобы он был десериализован в Bar или Baz.
Моя первая идея состояла в том, чтобы сначала десериализовать его в базовый класс, а затем использовать его тип и оператор switch, чтобы снова десериализовать JSON для его соответствующих учебный класс. (Использование Newtonsoft.Json
)
var type = JsonConvert.DeserializeObject<Base>(json).Type;
string message = "";
switch (type)
{
case (Base.SampleEnum.Bar):
message = JsonConvert.DeserializeObject<Bar>(json).BarOnly;
break;
case (Base.SampleEnum.Baz):
message = JsonConvert.DeserializeObject<Baz>(json).BazOnly;
break;
}
Console.WriteLine(message);
Нет необходимости говорить, что этот процесс чрезвычайно избыточен, утомителен и, поскольку оператор switch жестко запрограммирован, вовсе не очень «динамичен c».
Другая идея состояла в том, чтобы вместо этого использовать базовый класс generi c и передать тип фактического класса, в который он должен десериализоваться, но затем я получаю тот же оператор switch, чтобы выяснить, каким должен быть этот класс.
Поскольку вы не можете отобразить перечисления на типы классов, я также подумал об использовании словаря для сопоставления возможных значений перечислений с их аналогами классов; это все еще делает процесс отображения жестко запрограммированным.
Есть ли какой-либо способ, которым я могу динамически заставить соответствующий класс десериализоваться в зависимости от свойства типа объекта json?
РЕДАКТИРОВАТЬ: Кажется, есть некоторая путаница о том, как это предполагается использовать и как данные выбираются; позвольте мне предоставить некоторую справочную информацию.
Я перебираю каталог с большим количеством различных файлов электронных таблиц, в основном CSV и XML файлов. У каждого из этих каналов есть «метафайл», описывающий, как обрабатывать их содержимое. Это включает в себя контрольные суммы, разделители и другую информацию. Они также объявляют тип родительского файла (CSV, XML et c). Следовательно, они имеют много общих свойств (например, класс Base
в моем примере), но также имеют свой собственный набор свойств. Они происходят от абстрактного класса, который требует от них реализации функции, которая возвращает экземпляр соответствующего класса обработки каналов, инициализированный значениями непосредственно из метакласса. Я надеюсь, что это имеет смысл.