(JSON) 数据协定的复杂继承模式

本文关键字:复杂 继承 模式 JSON 数据 | 更新日期: 2023-09-27 18:37:00

>我从一个简单的数据模型开始:

{
    "Make" : "Honda",
    "Model" : "Civic",
    "Engine" : {
        "Location" : "Front"
    }
}

这个对象满足了我的用例,直到我得到了额外的要求,所以它变成了:

{
    "Make" : "Honda",
    "Model" : "Civic",
    "FuelType" : "Gasoline",
    "Engine" : {
        "Location" : "Front",
        "MPG" : 39
    }
}

{
    "Make" : "Tesla",
    "Model" : "Model S",
    "FuelType" : "Electric",
    "Engine" : {
        "Location" : "Back",
        "Range" : 300
    }
}

现在,我知道我不能在 C# 中使用派生返回类型重写,因此以下类结构将不起作用:

abstract class Car { abstract Engine Engine; }
class GasolineCar : Car { override GasolineEngine Engine; }
class ElectricCar : Car { override ElectricEngine Engine; }
abstract class Engine { string Location; }
class GasolineEngine : Engine { int MPG; }
class ElectricEngine : Engine { int Cells; }

是否有类似的推荐方法来模拟此数据模式?要求是:

  1. 我可以使用 JSON.NET 轻松反序列化它
  2. 我可以在 90% 的时间内使用基本的 Car & Engine 类型,并且仅在需要特定类型的字段时才强制转换它。

注意:请不要专门为上述示例提供替代解决方案。我对汽车一无所知,我的真实用例肯定需要使用这种模式或类似的东西。

(JSON) 数据协定的复杂继承模式

我认为你肯定把你的课程复杂化了。为什么不简单地使用这些类,json可以很容易地反序列化为这些类

class Car
{
    public string Make { get; set; }
    public string Model { get; set; }
    public string FuelType { get; set; }
    public Engine Engine { get; set; }
}
class Engine
{
    public string Location { get; set; }
    public string MPG { get; set; }
    public string Range { get; set; }
}

通常方法是这些被覆盖的字段不能被覆盖。所以你必须覆盖你的获取 - 设置方法

public abstract class Car { public virtual Engine Engine { get; set; } }
public class GasolineCar : Car {
    private GasolineEngine _engine;
    public override Engine Engine { get { return _engine; } set { this._engine = (GasolineEngine)value; } }
}
public class ElectricCar : Car
{
    private ElectricEngine _engine;
    public override Engine Engine { get { return _engine; } set { this._engine = (ElectricEngine)value; } }
}
public abstract class Engine { public string Location; }
public class GasolineEngine : Engine { int MPG; }
public class ElectricEngine : Engine { int Cells; }

或者,如果类型限制是重要的.

public abstract class Car<T> { public virtual T Engine { get; set; } }
public class GasolineCar : Car<GasolineEngine> {}
public class ElectricCar : Car<ElectricEngine>{}
public abstract class Engine { public string Location; }
public class GasolineEngine : Engine { int MPG; }
public class ElectricEngine : Engine { int Cells; }