我想得到一些正确的建议。 从继承的类访问属性数据的正确方法是什么。
假设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; }
}
我的第一个想法是创建一种某种类型的存储库,它为我提供了我正在寻找的任何属性。
我认为有两种类型的查询需要:
所以:
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;
}
在那里应该去的地方有点迷失但是我想避免反思,只是阅读集合和类类型等。
感谢您的任何建议。
答案 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>();
}