我有 2 组 2 个类,其中每对具有父类(super class)/子类关系,而正交对具有依赖关系。我试图确定的是如何处理属性的构造函数和/或主体,以使模型尽可能简单,数据重复最少。
代码结构如下:
public class Base1 {
public List<Base2> MyBase2Things { get; set; }
// Do things with Base2 objects
}
public class Sub1 : Base1 {
public List<Sub2> MySub2Things { get; set; }
// Do things with Sub2 objects and also with Base2 objects
}
public class Base2 {
public Base1 MyBase1 { get; set; }
// Do things with the Base1 object
}
public class Sub2 : Base2 {
public Sub1 MySub1 { get; set; }
// Do things with the Sub1 object
}
我考虑过覆盖子类中的基本属性,但这不太合适,因为子类中的属性没有相同的签名,所以我必须添加属性。
我也考虑过在子类的构造函数和set
方法中设置基属性,但是如果基类的属性更新了,子类的属性就没办法更新了.
还有哪些其他选项,哪个是最干净的(为什么)?
注意:为了说明问题,上面的代码大大简化了。真实类上还有其他属性和方法,但这个子集是我遇到的问题的本质。
最佳答案
我同意 Yaur 的观点,泛型可能有所帮助。至于您的选择并尽可能保持模型简单 - 这可能取决于具体情况,例如您的 4 个类的职责。
假设您正在处理各种车辆和车辆零件的父/子关系。
场景一:继承关系带来正交能力。
public class ItemParent { // formerly Base1
public List<ItemChild> MyChildren {get; set;}
}
public class ItemChild { // formerly Base2
public ItemParent MyParent {get; set;}
}
public class Car : ItemParent { // formerly Sub1
public List<CarPart> MyParts {get; set;}
}
public class CarPart : ItemChild { // formerly Sub2
public Car ParentCar {get; set;}
}
当然,Cars 应该特别了解 CarPart,而不是 ItemChild。所以你在这里求助于泛型。
public class ItemParent<T> where T : ItemChild {
public List<T> MyChildren {get; set;}
}
public class ItemChild<T> where T : ItemParent {
public T MyParent {get; set;}
}
public class Car : ItemParent<CarPart> {}
public class CarPart : ItemChild<Car> {}
public class Truck : ItemParent<TruckPart> {}
public class TruckPart : ItemChild<Truck> {}
您可以很好地调用 subclass.MyChildren[],或者创建一个委托(delegate)给 MyChildren 的 MyParts 属性。
在这个例子中,我认为模型非常简单,因为父/子隐喻非常容易理解。此外,如果您添加 Truck-TruckParts(或 Household-Resident、Shape-Line 等),您并没有真正增加复杂性。
这里的替代方法是将父/子“责任”移动到集合对象(可能是自定义的),如下所示:
public class ParentChildCollection<TParent, TChild> {}
public class Car {
private ParentChildCollection<Car, CarPart> PartHierarchy;
public List<CarPart> MyParts {get { return PartHierarchy.GetMyChildren(this); } }
}
public class CarPart {
private ParentChildCollection<Car, CarPart> PartHierarcy;
public Car ParentCar {get { return PartHierarchy.GetMyParent(this); }}
}
这里的缺点是,虽然干净,但 Truck 和 Car 可能不会共享很多代码(如果那是您想要的)。
场景 2:继承关系是关于专门化并行项目。
public class Car { // formerly Base1
public List<CarPart> MyParts {get; set;}
}
public class CarPart { // formerly Base2
public Car MyParent {get; set;}
}
public class Truck : Car { // formerly Sub1
public List<TruckPart> MyParts {get; set;}
}
public class TruckPart : CarPart { // formerly Sub2
public Truck MyParent {get; set;}
}
在这种情况下,Truck 和 Car确实共享更多代码。但这开始遇到即使使用泛型也不容易解决的签名问题。在这里,我会考虑使基类更通用 (Vehicle-VehiclePart)。或者考虑将第二种情况重构为第一种情况。或者使用集合进行父/子管理,使用静态继承进行 Car-Truck 代码整合。
无论如何,我不确定这两种情况是否符合您的情况。至少有一些因素取决于您如何(以及如何)安排您的人际关系。
关于c# - 如何在 C# 中干净地设计并行继承结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6045832/