【问题标题】:How to deserialize into collection of base type and then convert them to the concrete classes如何反序列化为基类型的集合,然后将它们转换为具体的类
【发布时间】:2022-07-14 22:58:06
【问题描述】:

我有一个字符串,我需要将其反序列化为一组对象,所有对象都继承同一个基类。

我的问题是,在我反序列化为基类集合后,编译器无法将每个项目识别为相关的具体对象。

这是我的代码:

public BaseClass // can be abstract
{
    int propA {get; set;}   
}


public ExtendedBaseClassA : BaseClass
{
    int propB {get; set;}   
    int propC {get; set;}   
}


public ExtendedBaseClassB : BaseClass
{
    int propD {get; set;}   
    int propE {get; set;}   
}

void Deserialize(string serializeMessage)
{
    IEnumerable<BaseClass> objects = JsonSerializer.Deserialize<IEnumerable<BaseClass>> 
    (serializeMessage);
    foreach(BaseClass item in objects)  
    {
        if (item is ExtendedBaseClassA) //never
        {
        }
        if (item is ExtendedBaseClassB) //never
        {
        }
    }
 }

还有其他方法吗?

【问题讨论】:

    标签: c# inheritance casting deserialization jsonserializer


    【解决方案1】:

    当您将字符串反序列化为BaseClass 时,它会分配propA。如果您要反序列化的 JSON 还包含 propBpropC 等,那么这些值会去哪里?他们无处可去。他们被丢弃了。反序列化不关心不属于被反序列化类型的属性。

    无论你告诉它反序列化为什么类型 - JsonSerializer.Deserialize&lt;Something&gt; - 它都会创建该类型的实例。它不会尝试确定是否存在可以基于不属于您指定类型的其他属性创建的继承类型。

    因此,一旦您反序列化为BaseClass,您所拥有的只是BaseClass 的一个实例。您可以将派生类型强制转换为基类型,但不能将基类型强制转换为其继承类型之一。

    我没有看到明显的解决方案,尤其是在不知道您正在使用的实际类型的细节的情况下。您可以将每个解析为JObject,查看它包含哪些属性,并决定将其反序列化为哪种类型。例如,如果它包含propE,则反序列化为ExtendedBaseClassB。如果不包含propE但包含propC,则反序列化为ExtendedBaseClassA,以此类推。

    更好的解决方案可能是创建一个包含所有可能属性的类型。如果它们可能没有被填充,则使它们可以为空。现在您可以将所有内容反序列化为一种类型并查看填充了哪些属性。你可能会发现你根本不需要继承。那将是理想的。 (这看起来像是可能不应该解决的问题类型 - 最好重新考虑,这样您就不会首先遇到问题。)

    或者如果您需要继承,那么在反序列化一个类之后,您可以编写一个函数来检查它,确定要创建的类型(取决于哪些属性)被填充,并创建一个“正确”类型的新实例.该函数可以将其作为基类返回,但实际类型可能是某个继承的类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-07
      • 2014-10-26
      • 2016-11-01
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多