C#从工厂返回通用接口

use*_*548 4 c# generics polymorphism

我已经实施了一项车辆服务,负责维修汽车和卡车等车辆:

public interface IVehicleService
{
    void ServiceVehicle(Vehicle vehicle);   
}

public class CarService : IVehicleService
{
    void ServiceVehicle(Vehicle vehicle)
    {
        if(!(vehicle is Car))
            throw new Exception("This service only services cars")

       //logic to service the car goes here
    }
}
Run Code Online (Sandbox Code Playgroud)

我还有一个车辆服务工厂,负责根据传入工厂方法的车辆类型创建车辆服务:

public class VehicleServiceFactory 
{
    public IVehicleService GetVehicleService(Vehicle vehicle)
    {
        if(vehicle is Car)
        {
            return new CarService();
        }

        if(vehicle is Truck)
        {
            return new TruckService();
        }

        throw new NotSupportedException("Vehicle not supported");
    }

}
Run Code Online (Sandbox Code Playgroud)

我的主要问题是具体CarService.ServiceVehicle方法.它接受一个Vehicle理想情况下它应该接受一个Car代替,因为它知道它只会服务汽车.所以我决定更新此实现以使用泛型:

public interface IVehicleService<T> where T : Vehicle
{
    void ServiceVehicle(T vehicle); 
}

public class CarService : IVehicleService<Car>
{
    void ServiceVehicle(Car vehicle)
    {
        //this is better as we no longer need to check if vehicle is a car

        //logic to service the car goes here 
    }
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是如何更新VehicleServiceFactory以返回车辆服务的通用版本.我尝试了以下但它导致编译错误,因为它无法将CarService转换为泛型返回类型IVehicleService:

public class VehicleServiceFactory 
{
    public IVehicleService<T> GetVehicleService<T>(T vehicle) where T : Vehicle
    {
        if(vehicle is Car)
        {
            return new CarService();
        }

        if(vehicle is Truck)
        {
            return new TruckService();
        }

        throw new NotSupportedException("Vehicle not supported");
    }

}
Run Code Online (Sandbox Code Playgroud)

任何建议,将不胜感激.

InB*_*een 5

只需将服务转换为界面:

return new CarService() as IVehicleService<T>;
Run Code Online (Sandbox Code Playgroud)

知道T是汽车,但编译器没有,它不够聪明,不能遵循方法逻辑,也不是意味着; 就编译器所知,T可以是任何东西,只要它的一个Vehicle.你需要告诉编译器,"嘿,我知道我在做什么,TCar其实都是同一类型的."

  • 这也是一个正确的答案,问题仍然存在:你打算用`IVehicleService <T>`返回的值做什么?对于每种类型的服务,您将需要不同类型的变量.声明这样的接口可能更有用:`public interface IVehicleService <T>:IVehicleService`.也就是说,您从非泛型接口派生出通用接口.这使您可以以中立的方式使用车辆服务.您可以以通用方式实现,但以非泛型方式使用.您甚至可以创建包含不同类型服务的`List <IVehicleService>`. (2认同)