c# - C# 将 JSON 反序列化为依赖于类型属性的类
问题描述
假设我有这个小 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;
}
}
基于 json 片段中的 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
我的示例中的类),但也有自己的一组属性。它们派生自一个抽象类,该类要求它们实现一个函数,该函数返回相应的提要处理类的实例,并直接使用元类中的值进行初始化。我希望这是有道理的。
解决方案
@OguzOzgul 评论是正确的。对于由需要序列化和反序列化的接口组成的对象,我已经做了无数次。
请参阅 Newtonsoft 的 TypeNameHandling: https ://www.newtonsoft.com/json/help/html/SerializeTypeNameHandling.htm
您的 json 文件看起来会略有不同:
{
"$type": "SomeNamespace.Bar",
"BarOnly": "This is a string readable when deserialized to the Bar class only, as declared in my type key"
}
如果你使用
new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
}
在序列化过程中,它将添加所有对象的完整类型名称,以确保 newtonsoft 在反序列化过程中知道它们的类型(假设您使用相同的设置)。这样您就不必为类型检测编写自己的自定义代码。
推荐阅读
- python - 为什么我的脚本不显示新创建的文件?
- excel - 跨多个表的 DAX 乘法总和 (sumproduct)
- core-data - 将核心数据传递给子视图
- javascript - 如何在 Qualtrics 调查中隐藏下一个按钮直到一天中的某个时间
- java - 处理目录和文件时处理 IO 异常的最佳实践?
- sql - 在 Firebird 中选择最接近的最大数值
- node.js - lambda 函数中的 AWS NodeJS lambda 调用
- google-apps-script - 谷歌表返回有多少标签可见
- python - r.write('\n') 切断需要的数据
- mysql - 如何更改 mysql 中的服务器字符集(LAMP 堆栈)