将对象序列到JSON后,我们如何保留多态性
在将配置文件保存到数据库之后,我们在系统中存在一个复杂的问题。
为了这个问题,我们简化了问题。请参阅下面的代码。
这是代码:
class Wheel
{
public virtual string GetWidth()
{
return "Normal";
}
}
class SmallWheel : Wheel
{
public override string GetWidth()
{
return "Small";
}
}
class BigWheel : Wheel
{
public override string GetWidth()
{
return "Big";
}
}
public static async Task Main(string[] args)
{
//Build list of wheels
var wheels = new List<Wheel>()
{
new Wheel(),
new SmallWheel(),
new BigWheel(),
};
//We print wheels to check it works
foreach (var x in wheels)
{
Console.WriteLine(x.GetWidth());
}
//Save the list to the db as a string
var file = JsonConvert.SerializeObject(wheels);
//We just use file instead of db for simplictiydf
//Later we read the config file from the DB
var wheelsFromDb = JsonConvert.DeserializeObject<List<Wheel>>(file);
//We now want to print out our wheels.
Console.WriteLine("Printing WHeels from Db");
foreach (var x in wheelsFromDb)
{
Console.WriteLine(x.GetWidth());
}
}
当我运行时的结果:
Normal
Small
Big
Printing WHeels from Db
Normal
Normal
Normal
现在,如您所见,我们正在丢失De-serialise化后的车轮类型。
我们如何解决这个问题?
从本质上讲,我们需要存储一个带有多个儿童课程的配置文件,每个类别都具有覆盖功能。我意识到,当JSON对原始字符串的估计时,它没有以前哪种类型的上下文。有什么方法可以存储该上下文或使用其他库或数据库?
We have a complex issue in our system regarding retaining polymorphism after we have saved a config file to the database.
We have simplified the problem for the sake of this question. See code below.
Here is the code:
class Wheel
{
public virtual string GetWidth()
{
return "Normal";
}
}
class SmallWheel : Wheel
{
public override string GetWidth()
{
return "Small";
}
}
class BigWheel : Wheel
{
public override string GetWidth()
{
return "Big";
}
}
public static async Task Main(string[] args)
{
//Build list of wheels
var wheels = new List<Wheel>()
{
new Wheel(),
new SmallWheel(),
new BigWheel(),
};
//We print wheels to check it works
foreach (var x in wheels)
{
Console.WriteLine(x.GetWidth());
}
//Save the list to the db as a string
var file = JsonConvert.SerializeObject(wheels);
//We just use file instead of db for simplictiydf
//Later we read the config file from the DB
var wheelsFromDb = JsonConvert.DeserializeObject<List<Wheel>>(file);
//We now want to print out our wheels.
Console.WriteLine("Printing WHeels from Db");
foreach (var x in wheelsFromDb)
{
Console.WriteLine(x.GetWidth());
}
}
Results when I run it:
Normal
Small
Big
Printing WHeels from Db
Normal
Normal
Normal
Now as you can see we are losing what type the wheel is after de-serialisation.
How can we go about solving this issue?
In essence, we need to store a config file with multiple children classes each with overrides functions. I realise that when Json deserializes the raw string it has no context of what type the class was before. Is there a way we can store that context or use a different library or database?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我正在将此代码用于派生类列表。您可以使用基类,而不是界面以及
类
I am using this code for a list of derived classes. You can use a base class instead of an interface as well
classes
JSONCONVERT
在使用typenamehandling.all
时,在引擎盖下创建属性。因此,我们可以通过创建类中的
size
属性来为编译器提供有关哪种类型的线索:这是一个包含车轮大小的类:
到目前为止,太好了。但是,我们如何根据尺寸的车轮对JSON进行测试?我们可以编写Custom Deserializer:
这是一个在较低情况下创建JSON的类:
这是一个基于大小创建对象的工厂:
然后您可以运行代码:
JsonConvert
creates property$type
under the hood whenTypeNameHandling.All
is used.So we can give a clue to compiler about what type actually is by creating
Size
property in classes:This is a class which contains size of wheels:
So far, so good. But how we can deserialize json based on size wheel? We can write custom deserializer:
This is a class to create json in lower case:
This is a factory which creates an object based on size:
And then you can run code like this: