继承属性类的 c# OO 建议

标签 c# oop inheritance

请给我一些面向对象的正确建议。 从继承类访问属性数据的正确方法是什么。

假设有 3 个类:

public abstract class Vehicle
{
  public int Id {get; set; }    
  public int Wheels {get; set; }
  public string Name {get; set; }
  public string Color {get; set; }
 }
 public class Car : Vehicle
 {
 }
 public class Truck : Vehicle
 {
  public int LoadCapacity {get; set; }  
 }

我的第一个想法是创建某种存储库,为我提供所需的属性。

我认为我需要两种类型的查询:

  1. 返回具有特定 ID 的车辆的属性
  2. 给我特定类型的所有车辆

所以:

public class VehicleRepository
{
    ICollection <???> _vehicles;

    ??? GetVehicle(int Id);
    ??? GetVehicles(??? vehicleType);
}

那个???是我的未知数。

我的想法是为 IVehicle 添加类似接口(interface)的东西,并用它来实现 Vehicle。 结果将类似于:

public class VehicleRepository
{
    ICollection <IVehicle> _vehicles;

    IVehicle GetVehicle(int Id);
    ICollection <IVehicle> GetVehicles(IVehicle vehicleType);
}

这显然行不通。

public IVehicle GetVehicle(int Id)
{
    return _vehicles.First(x=>x.Id == Id);
    // The above want compile as the interface has no attributes
}

如果我使用 Vehicle 而不是 IVehicle,'First(x=>x.Id == Id)' 将正常工作,但如果车辆是卡车,它不会返回 'LoadCapacity'。

查看 GetVehicles 函数,我在想:

public ICollection <T> GetVehicles <T> ()
{
    var vehicles = _vehicles.Where(???);
    return vehicles;
}

对于应该放在那里的内容有点迷茫,但我想避免反射(reflection),只阅读程序集和类类型等。

感谢您的任何建议。

最佳答案

要存储和获取 vericles,您需要做的就是:

class VehicleRepository {
    List<Vehicle> vehicles;
}

要检索它们,只需使用 IEnumerable<T>.OfType<U>() :

VehicleRepository repository = ...
repository.vehicles.OfType<Car>(); // This will get you all of the cars
repository.vehicles.OfType<Truck>(); // This will get you all of the trucks

不过,如果你想花哨一些,你可以制作 VehicleRepository一个完全属于自己的集合,使其实现 IEnumerable<T> .考虑:

class VehicleRepository : IEnumerable<Vehicle> {
    List<Vehicle> vehicles;

    public IEnumerator<Vehicle> GetEnumerator() {
        return vehicles.GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
        return this.GetEnumerator();
    }
}

然后您可以查询集合本身,如:

public static void Main() {
    VehicleRepository repository = ...;

    // Notice that we skip accessing the vehicles member
    // because by implementing IEnumerable<T> this class
    // becomes a collection. Now you can use OfType<T> directly.
    repository.OfType<Car>(); 
}

编辑:做类似 GetVehicleByID 的事情,你可以尝试这样的事情:

class VehicleRepository : IEnumerable<Vehicle> {
    List<Vehicle> vehicles;

    public Vehicle GetVehicleByID(Int32 id) {
        return vehicles[id];
    }
}

你也可以使用索引器,像这样:

class VehicleRepository : IEnumerable<Vehicle> {
    List<Vehicle> vehicles;

    public Vehicle this[Int32 id] {
        get { return vehicles[id]; }
    }
}

获取LoadCapacity从卡车上,你所要做的就是这样:

public static void Main() {
   VehicleRepository repository = ...

   // Assuming index zero is a truck
   Truck truck = (Truck)repository.GetVehicleByID(0);
   truck.LoadCapacity = ...
}

在不使用反射的情况下获取特定类型的所有项目(当绑定(bind)到 UI 时,即假设您使用 Strings )的一种作弊方法是匹配 ToString类型名称的值。例如:

public static void Main() {
   VehicleRepository repository = ...

   // Assume we're storing off the typename in the UI dropdown.
   // so that when the user selects it, we automatically have the correct
   // type name we want to filter by.
   String truckTypeName = typeof(Truck).GetType().ToString();      

   // Filter only by those types with a matching type name. Inefficient,
   // but it does avoid reflection.
   repository.Where(vehicle => vehicle.GetType().ToString() == truckTypeName)
}

关于继承属性类的 c# OO 建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19210847/

相关文章:

c++ - 如何在C++中添加类?

c# wpf 数据绑定(bind)没有发生。

c# - 在c#中创建时间事件

c# - 如何避免回发代码并改用超链接?

php - 通过字符串获取 PHP 类属性

java - 当您在其中调用另一个方法时,方法的执行流程是否等待?

c++ - 错误 - 不完整类型/前向声明的无效使用

c# - 如何仅使用基类中的代码返回派生类?

c# - 为什么平方根运算这么慢?

python - 非常大的 __init__ 有什么问题吗?