【发布时间】:2014-11-23 20:00:57
【问题描述】:
EDIT4 为 Truck 提供了一个属性,以显示 SetNrOfWheels 方法是为特定的 Truck 量身定制的
EDIT3 在 B - Vehicle 和 C1 - Truck 之间建立了连接
EDIT2 移除了 B 上的界面
EDIT1 将汽车改为车辆
关于我多次遇到的问题,我有两个问题。我想知道我是否必须使用另一种模式,或者是否有人可以为我指出正确/更好的方向。
如果你知道这里有一篇描述答案的文章,请告诉我,我会尝试删除这篇文章。
考虑一个抽象基类B(即Vehicle),它被多个子类C1、C2等(即Truck、Motor)继承。假设这些类是纯数据载体,即数据契约,并且包含的一些属性。尽管对于故事来说不是绝对必要的,但它们使用了一个没有参数的默认构造函数,并且所有属性都是公共的,并且是简单的值类型对象。它们可能继承也可能不继承一些预定义的属性,但最重要的是,B 或多或少是一个标记,而不是强制执行功能(因为它是一个数据契约)。
例子:
abstract Vehicle {
int NrOfWheels { get; set;}
}
Truck : Vehicle {
bool HasExtraTrailer { get; set; }
}
现在考虑一个 B 的操纵器,称为 BM(即 VehicleWheelSetter),它要么是抽象基类,要么是一个接口(你决定什么是最好的;))。它具有(至少是抽象的)操作 B 类的功能。假设每个机械手,即 C1M, C2M, (TruckWheelSetter, MotorWheelSetter) 都继承自 BM。重要的是,类型是强制的,因此,C1M 仅操作 C1 类型的类。这可以通过通用的 BM 来强制执行,比如 BM
例子:
interface IVehicleWheelSetter<in T> where T : Vehicle {
void SetNrOfWheels(T vehicle)
}
TruckWheelSetter : IVehicleWheelSetter<Truck> {
void SetNrOfWheels(Truck vehicle) {
vehicle.NrOfWheels = 2 * 3;
if (vehicle.HasExtraTrailer) vehicle.NrOfWheels += 2 * 2;
} } }
问题 1:有没有办法确保一个具体的 BM(即 C1M)总是操纵一个具体的 B(在这种情况下是 C1)?还是需要其他模式?
假设一般来说,这比分配一个数字要复杂得多(显然可以从配置或数据库中检索)。我写 2 * 3 并不是巧合,以表明这可能是一个复杂的操作。
假设我知道我总是在一些必须进行操作的服务中获得 B 类,比如工厂,像这样:
VehicleWheelSetterFactory {
IVehicleWheelSetter<T> CreateVehicleWheelSetter<T>() where T : Vehicle {
// code to create the right selector here
} }
现在,有多种方法可以做到这一点:
if (typeof(T) == typeof(Truck))
return (IVehicleWheelSetter<T>)(new TruckWheelSetter());
throw new NotImplementedException();
或一些更高级的基于反射的选项。
这有一些问题,除了一些“感觉不对”。也会有泛型不起作用的情况,即 T 是未知的。在这种情况下,参数中的类型可能会有所帮助:
object CreateVehicleWheelSetter(Type vehicleType) {
if (vehicleType == typeof(Truck))
return new TruckWheelSetter();
throw new NotImplementedException();
}
但是如何将对象转换为 IVehicleWheelSetter
interface ICarWheelSetter
{
void SetNrOfWheels(Vehicle vehicle);
}
但现在我遇到了最初的问题:我不能保证 Vehicle 是 TruckWheelSetter 中的卡车。这也不能这样解决:
interface IVehicleWheelSetter
{
void SetNrOfWheels<T>(T car) where T : Vehicle;
}
问题 2:有更好的方法吗?
【问题讨论】:
-
看看这个答案,看看它在这种情况下是否有帮助:stackoverflow.com/a/5386425/259769
-
"如果您知道这里有一篇描述答案的文章,请告诉我,我会尽量删除这篇文章。"请不要那样做。如果问题是重复的,它将被标记为重复问题并与现有答案链接。
标签: c# .net wcf generics inheritance