c#对继承属性类的OO建议

时间:2013-10-06 16:02:28

标签: 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. 给我所有特定类型的车辆
  3. 所以:

    public class VehicleRepository
    {
        ICollection <???> _vehicles;
    
        ??? GetVehicle(int Id);
        ??? GetVehicles(??? vehicleType);
    }
    

    ???是我的未知数。

    我的想法是为IVehicle添加类似界面的东西并用它实现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 =&gt; x.Id == Id)'将正常工作但如果车辆是卡车则不会返回'LoadCapacity'。

    看看GetVehicles函数,我想的是:

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

    在那里应该去的地方有点迷失但是我想避免反思,只是阅读集合和类类型等。

    感谢您的任何建议。

2 个答案:

答案 0 :(得分:3)

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

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 = ...
}

获取特定类型的所有项目(绑定到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)
}

答案 1 :(得分:0)

您可以使用OfType方法获取特定类型集合中的项目:

public ICollection<T> GetVehicles<T>() {
  return _vehicles.OfType<T>();
}