DeSerialize为未知的派生类型

本文关键字:派生 类型 未知 DeSerialize | 更新日期: 2023-09-27 18:22:06

我将一个序列化的对象存储为数据库中的json(将来可能是xml)。在稍后的某个时刻,此对象将被拉出并序列化。基类是HighChart,但也有一些派生类型,如HighChart.ColumnBarChart。图表的类型存储在JSON中。问题是我不知道如何动态地选择要反序列化为.的类

我的解决方案需要提供一种自动考虑未来派生类型的方法(我将扩大图表类型的数量,不想为每种图表类型编写新的程序)。

我知道我可以将类型存储到一个单独的DB字段中,但同样,我必须在反序列化方法中为每个类型使用switch语句。我也可以解析json字符串并发现图表类型,但同样,我必须对每种可能的类型使用switch语句。

谢谢你的想法!

DeSerialize为未知的派生类型

如果将新类型的Assembly Qualified Name存储在数据库中,则可以使用该名称实例化该类型的实例,而无需更改类型加载代码。实现如下所示:

        string assemblyQualifiedName = getAssemblyQualifiedNameFromDatabase();
        var futureType = Type.GetType(assemblyQualifiedName);
        var serializer = new DataContractJsonSerializer(futureType);
        var result = (HighChart)serializer.ReadObject(stream);

请注意,没有案例陈述:没有必要事先知道实际类型。但是,此代码假设您已经将新类型直接包含在项目中或通过引用包含在内。如果要使用未使用对新类型的引用重新编译的程序集动态加载新类型,则必须加载包含新类型的程序集并使用对已加载程序集的引用才能创建类型引用。

您提到您无法轻松地从基类型转换为派生类型。为什么?我做到了。我的Dog实体有一个属性(DogYears),在Animal基类型中不存在,但我仍然可以将Dog反序列化为Animal,然后对其进行强制转换并显示DogYear。

public class Dog : Animal
{
    public int DogYears { get; set; }  // This doesn't exist in the base class
    public Dog()
    {
        this.DogYears = 4;
    }
}

在这里,我们将Dog序列化为基类型,然后将其反序列化为基型,但我们仍然可以显示特定于Dog的属性:

private static void JsonSerialization()
{
    Animal dog = new Dog();
    var stream = new MemoryStream();
    var serializer = new DataContractJsonSerializer(typeof(Animal));
    serializer.WriteObject(stream, dog);
    stream.Position = 0;
    Animal deserializedDog = serializer.ReadObject(stream) as Animal;
    Console.WriteLine(((Dog)deserializedDog).DogYears);
}

控制台正确显示"4"。

为了完整起见,这里是动物类:

[KnownType(typeof(Dog))]
public abstract class Animal
{
    // Properties here
}