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

时间:2016-03-01 09:26:19

标签: c# json oop inheritance json.net

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

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

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

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

OR

{
    "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. 轻松地反序列化它
  3. 我可以使用基本的Car&引擎类型占90%的时间,仅在需要特定于类型的字段时才进行转换。
  4. 注意:请不要专门针对上述示例提供备用解决方案。我对汽车一无所知,我的真实用例肯定需要使用这种模式或类似的东西。

2 个答案:

答案 0 :(得分:2)

我认为你肯定会使你的课程变得复杂。为什么不简单地使用这些类,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; }
}

答案 1 :(得分:0)

通常方法是这些被覆盖的字段不能被覆盖。所以你必须覆盖你的Get - Set Methods

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; }