【发布时间】:2020-04-19 18:03:43
【问题描述】:
假设我有这个小 json sn-p:
{
"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;
}
}
基于 json sn-p 中的 Type 属性,我希望将其反序列化为 Bar 或 Baz。
我的第一个想法是首先将其反序列化为 Base 类,然后使用其类型和 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 语句是硬编码的,因此根本不是很“动态”。
另一个想法是使用泛型类作为基类,并传入它应该反序列化到的实际类的类型,但我最终会使用相同的 switch 语句来确定该类应该是什么。
由于您无法将枚举映射到类类型,因此我还考虑使用 Dictionary 将可能的枚举值映射到其对应的类;不过,这仍然会使映射过程硬编码。
有什么方法可以根据 json 对象的 type 属性动态获取要反序列化的相应类?
编辑:对于应该如何使用它以及如何获取数据似乎有些混乱;让我提供一些背景信息。
我正在遍历一个包含许多不同电子表格文件的目录,主要是 CSV 和 XML 文件。这些提要中的每一个都有一个“元文件”,描述如何处理它们的内容。这包括校验和、分隔符和其他信息。他们还声明其父文件的类型(CSV、XML 等)。因此,它们共享许多公共属性(例如我的示例中的 Base 类),但也有自己的一组属性。它们派生自一个抽象类,该类要求它们实现一个函数,该函数返回相应的提要处理类的实例,并直接使用元类中的值进行初始化。我希望这是有道理的。
【问题讨论】:
-
使用反射找到对应的类,然后使用反射调用方法进行反序列化。
-
一般情况下Newtonsoft Json可以将$type信息放入json内容中。这是
Type财产吗? -
@LasseV.Karlsen 当然,反思始终是一个答案;)不过,如果有其他方法,我不想弄脏它。
-
为什么不把抽象方法放到基类中,让扩展类实现它,比如公共抽象字符串GetMessage();
-
那么,Bar 可以返回 BarOnly,Baz 可以返回 BazOnly,而您对具体类一无所知?没有枚举,没有类型检查,我猜是“动态”的东西 :)
标签: c# json class generics types