c# - 如何在 C# 中干净地设计并行继承结构?

标签 c# inheritance subclass

我有 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/

相关文章:

c++ - 使用指向基抽象类的指针访问子类成员

c# - 使用 ItemAppearing 事件在 ListView 中向下滚动会跳过 Xamarin.Forms 中的记录

c# - 如何在不更改数据库中的真实数据的情况下知道我的查询是否有错误?

java - 在Java中如何使用接受其父类的单个函数处理所有子类

java - 如何强制子类调用抽象实现的方法

objective-c - 防止在 Swift 中子类化 Objective-C 类

wpf - XAML 子类类型声明设计器错误

c++ - 如何统计模板类的CRTP子类个数?

c# - 提交时下拉值重置为初始值

c# - 如何在 grpc 中返回 list<model>