Rewriting your code to such an extent that I can make it fail when you say it will be - the problem is exactly what Tom Smith says: PickupTruck inherits Car and therefore is Vehicle<Car, ParkingLot> and not Vehicle<PickupTruck, ParkingLot> . In addition, because of this common inheritance, it is impossible for it to be anything other than this.
I know that your code is only a concise representation of the problem you are facing, but if it is close enough, there may be some useful points that we can make here about the general architecture.
I am not opposed to making common bases aware of my colleagues - indeed, this is especially useful for factories; however, it almost always instantly excludes further inheritance.
You are trying to encode too much information at the type level; and besides the number of angle brackets that we see here, it actually hints at a slightly inappropriate character that Vehicle<TVehicleType, TStorage> determines the type of storage that it can store inside.
It just doesnβt make any sense to me, because they say that we have ParkingLot today, but tomorrow we also get Hangar (for cars that are stored undercover) - this will require a completely new swathe of types of vehicles that are unequal in due to the fact that we also have a derived type passed to the Vehicle<TDerived, ...> ParkingLotCar - ergo ParkingLotCar , and HangarCar never be equivalent, even if two instances represent the same make / model, etc.
So, expecting this, you went on an inheritance, where you have a common Car , but, of course, at this point, any inheritance is meaningless, because Car is Vehicle<Car,...> , so all that should be from it should be. Only with multiple inheritance, perhaps this is not so, but even with this he did not go around the whole ParkingLot issue.
Ask yourself why Vehicle<,> needs to know about the type of receipt? Does this mean that you can have one factory method? In this case, you must put it in the Dealership or ParkingLot ; Not Vehicle Base:
public interface IVehicle {} public interface ICar : IVehicle {}
You now have a time relationship between vehicle types; allowing various specific types to share features, such as ICar or IPickup ; but you have broken the connection between the car and the storage so you can get IVehicle from FootballPitch or disconnect it from the pier to RiverBed if you need to.