多态重载 - 为了重载参数的目的,如何强制抽象类型"作用"为其派生类型之一?

Cer*_*rzi 5 c# polymorphism overloading

DoSomething(Car car);
DoSomething(Bike bike);

public class Car : Vehicle {}
public class Bike : Vehicle {}
public abstract class Vehicle {}


void run(Vehicle vehicle) {
    DoSomething(vehicle);
}
Run Code Online (Sandbox Code Playgroud)

这感觉就像一个简单的问题,但我遇到了问题.DoSomething(车辆车辆)不存在,因此即使车辆"保证"为汽车或自行车,DoSomething(车辆)也会抛出错误.我怎样才能说服编译器"车辆"是自行车还是汽车,以便可以运行DoSomething?

当然,我可以采用另一种方法

DoSomething(Vehicle vehicle)
{
    if(vehicle is Car) ... etc
}
Run Code Online (Sandbox Code Playgroud)

但肯定有更清洁的方法吗?

编辑/ CLARITY

将此代码放在管理器类中而不是在Vehicle类中存在DoSomething()的动机是每个Vehicle需要访问程序的不同部分.例如:

DoSomething(Car car) {
    motorwayInfo.CheckMotorwayStatus();
}
DoSomething(Bike bike) {
    cycleInfo.CheckCyclePathStatus();
}
Run Code Online (Sandbox Code Playgroud)

不确定这个类比是否真的能够解决我的特定问题,哈哈 - 但基本上我不希望Car有任何对cycleInfo的引用,也不希望Bikes对motorWayInfo有任何引用.但是,将DoSomething放入车辆基本上意味着它的参数需要是:

DoSomething(CycleInfo cycleInfo, MotorwayInfo motorwayInfo)
Run Code Online (Sandbox Code Playgroud)

要么

DoSomething(InfoManager infoManager)
Run Code Online (Sandbox Code Playgroud)

这些都不是完全理想的,因为我知道每个子类型只会使用特定的信息对象.我错了吗?

Zor*_*vat 5

这里真正的问题是 - 你对该方法的参数有什么期望?如果它,无论它是什么,取决于参数的具体(子)类型,那么该行为的适当位置是在参数基类的虚拟(甚至抽象)成员中 - Vehicle.

class Vehicle
{
    public abstract void Behave();
}

class Car : Vehicle
{
    public override void Behave()
    {
        // Do something specific to a car
    }
}

class Bike : Vehicle
{
    public override void Behave()
    {
        // Do something specific to a bike
    }
}
...
void Run(Vehicle vehicle)
{
    vehicle.Behave();
}
Run Code Online (Sandbox Code Playgroud)

从这段代码中可以看出,我已经恢复了角色.该Run函数负责知道具体参数应如何表现.相反,作为Vehicle参数传递的每个具体对象都必须知道如何表现.这是正确的多态性.

关于该Run方法,关于参数的所有责任应该与所有参数对象的公共类型相关,即基类Vehicle.在这方面,该方法可以访问在基类上定义的成员,或者将对象插入集合等.

void Run(Vehicle vehicle)
{
    vehicle.Behave();

    List<Vehicle> list = ...
    list.Add(vehicle);
}
Run Code Online (Sandbox Code Playgroud)