使用抽象中不存在的属性实现通用抽象方法 class

Implement generic abstract method with properties not present in abstract class

我有以下设置:

抽象class 具有以下简化结构的车辆:

public abstract class Vehicle
{
    public string Brand { get; set; }
    public string Model { get; set; }
    public string GetBasicInfo(Vehicle v)
    {
        return string.Format("This car was produced by {0}. The Model is {1}.", Brand, Model);
    }
    abstract public string GetVehicleData<T>(T vehicle) where T : Vehicle;
}

然后我有一个 class Car 继承自 Vehicle,它有自己的一些属性:

public class Car : Vehicle
{
    public bool Is4x4 {get;set;}
    public override string GetVehicleData<Car>(Car vehicle)
    {
        return String.Format("Brand: {0}, Model: {1}, Is4x4: {2}", vehicle.Brand, vehicle.Model, vehicle.Is4x4);
    }
}

当我尝试访问 vehicle.Is4x4 时出现错误,即 Car 不包含 Is4x4 的定义。我研究了 SO 并发现,由于 属性 Is4x4 未在抽象父 class 中定义,因此无法在覆盖方法中调用它。

为了避免这个问题,我改变了 2 classes 如下:

public abstract class Vehicle
{
    public string Brand { get; set; }
    public string Model { get; set; }
    public string GetBasicInfo(Vehicle v)
    {
        return string.Format("This car was produced by {0}. The Model is {1}.", Brand, Model);
    }
    abstract public string GetVehicleData(Vehicle vehicle);
}

还有车class:

public class Car : Vehicle
{
    public bool Is4x4 {get;set;}
    public override string GetVehicleData(Vehicle vehicle)
    {
        Car vehicleCast = (Car)vehicle;
        return String.Format("Brand: {0}, Model: {1}, Is4x4: {2}", vehicleCast.Brand, vehicleCast.Model, vehicleCast.Is4x4);
    }
}

此代码编译并允许我在 GetVehicleData 方法中添加子 class 特定属性。但是我觉得应该有更好的方法来解决这个常见问题。

问题出在这一行:

public override string GetVehicleData<Car>(Car vehicle)

这与写法相同:

public override string GetVehicleData<T>(T vehicle)

... 除了您使用 Car 作为类型参数的名称,而不是更传统的 TCar 没有引用 class Car,而是引用了一个新的泛型类型参数。

当您重写泛型方法时,语言不会强制您使用相同类型的参数名称:您可以这样写

public abstract class Vehicle
{
    public abstract string GetVehicleData<T>(T vehicle) where T : Vehicle;
}

public class Car : Vehicle
{
    public abstract string GetVehicleData<T2>(T2 vehicle) { ... }
}

...并且您已选择使用 Car 而不是 T2.


要解决根本问题,您不能定义基本方法 Vehicle.GetVehicleData(Vehicle vehicle),然后用更具体的 Car.GetVehicleData(Car car) 覆盖它。如果有人这样做会叫什么 new Car().GetVehicleData(new Truck())?

Car 的 GetVehicleData 方法需要能够接受任何类型的 Vehicle

就是说,目前还不清楚为什么您的 GetVehicleData 使用第二辆车,而不是仅仅在其定义的实例上运行。

这样写比较正常:

public abstract class Vehicle
{
    public string Brand { get; set; }
    public string Model { get; set; }
    public string GetBasicInfo()
    {
        return string.Format("This car was produced by {0}. The Model is {1}.", Brand, Model);
    }
    public abstract string GetVehicleData();
}

public class Car : Vehicle
{
    public bool Is4x4 {get;set;}
    public override string GetVehicleData()
    {
        return String.Format("Brand: {0}, Model: {1}, Is4x4: {2}", Brand, Model, Is4x4);
    }
}