无论如何在 C# 中反序列化之前检查对象的类类型?

Posted

技术标签:

【中文标题】无论如何在 C# 中反序列化之前检查对象的类类型?【英文标题】:Is there anyway to check the class type of an object BEFORE deserializing in C#? 【发布时间】:2022-01-04 22:10:16 【问题描述】:

例如,我有几种类型的汽车被序列化为 .car 文件(这是一个学校项目)。我有三种不同的类型,福特、雷克萨斯和道奇。我可以很好地保存它们。但是以我的程序的当前架构,当我反序列化时,我需要知道 before 反序列化的类型。例如我是这样序列化的:

if (CurrentCar.GetType() == typeof(Ford))

   var JSON_CAR = JsonSerializer.Serialize((Ford)CurrentCar);
   writer.Write(JSON_CAR);

当我反序列化时,我需要在反序列化之前知道类型:

CurrentCar = JsonSerializer.Deserialize<???>(reader.ReadString());

我怎样才能做到这一点?谢谢。

【问题讨论】:

如果您需要帮助,您必须发布您的 json。还有你的课。 康纳你有没有找到更好的方法来做到这一点 @Chrispie 很遗憾没有,我必须遵循本教程:docs.microsoft.com/en-us/dotnet/standard/serialization/…。这有点霸道,但我没有找到更好的方法。 【参考方案1】:

如果你不知道汽车的确切类型,你的 Json 应该包含持有它的类型的属性


  "CarManufacturer" : "FORD"

您可以手动将此属性添加到您的课程中

enum CarManufacturer

    FORD,
    BMW

class Car

    [JsonConverter(typeof(JsonStringEnumConverter))]
    public CarManufacturer Manufacturer  get; set; 
    public string Name  get; set; 


class Ford:Car

    public Ford()
    
        Manufacturer = CarManufacturer.FORD;
    
    public string OnlyFord  get; set; 


class BMW :Car

    public BMW()
    
        Manufacturer = CarManufacturer.BMW; ;
    
    public string OnlyBMW  get; set; 

你可以将它序列化如下

Car CurrentCar = new Ford  Name = "Foard Car", OnlyFord = "spacific feature in Ford Cars" ;
string json = JsonSerializer.Serialize(CurrentCar, CurrentCar.GetType());
Console.WriteLine(json);

反序列化

Car Tempcar = JsonSerializer.Deserialize<Car>(json);
var Car = Tempcar.Manufacturer switch

    CarManufacturer.BMW => JsonSerializer.Deserialize<BMW>(json),
    CarManufacturer.FORD => JsonSerializer.Deserialize<Ford>(json),
    _ => Tempcar
;

这应该可以解决您的问题,但它有一些缺点

    您将对同一个对象进行两次反序列化! 为模型添加一些属性以用作类型鉴别器 如果您的基类是抽象类,此解决方案将不起作用

为了克服这个问题,你应该写Custom converter Support polymorphic deserialization这会自动将类型鉴别器添加到生成的json中,而不会给你的类添加任何值

【讨论】:

感谢您的教育回答!另一种方法是拥有一个具有一堆可为空属性的容器类,每个可能类型的 Car 一个,然后序列化该容器类?对我来说,这听起来相当于 Google Protocol Buffers OneOf 或 ASN.1 的 CHOICE,这听起来像是提问者想要的。我不知道 C# 在序列化为 JSON 时是否可以处理这样的类(我不是 C# 专家),但如果它确实有效,那么它将是一个单一的反序列化。可能另一种方法是实际使用带有 JSON 线格式的 GPB 或 ASN.1,省去编写大量代码。

以上是关于无论如何在 C# 中反序列化之前检查对象的类类型?的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中反序列化复杂对象

如何在 C# .NET 中反序列化复杂的 JSON 对象?

当您没有类型时,如何在 .NET 中反序列化 JSON 字符串

C# 在单个对象中反序列化两个 Jarray 对象

使用 LitJson 在 C# 中反序列化 JSON 对象数组 [重复]

如何在 C# 中反序列化具有前缀的 XML