3

Let's assume we have following classess:

abstract class Vehicle {/**/}

class Truck : Vehicle {/**/}
class Bus : Vehicle {/**/}
//etc...

abstract class VehicleWheel<TVehicle> where TVehicle : Vehicle {/**/}

class TruckWheel : VehicleWheel<Truck> {/**/}
class BusWheel : VehicleWheel<Bus> {/**/}

Now, i want to create generic class "VehicleWheelCarrier", which is inherited from Vehicle, and has 1 parameter, which is any type of wheel:

abstract class VehicleWheelCarrier<TWheel> : Vehicle where TWheel:VehicleWheel

Unfortunatelly, this doesn't compile, as VehicleWheel requires parameter.

How to solve that?

2
  • 1
    Provide the parameter. Commented Feb 22, 2018 at 7:09
  • 4
    So, the VehicleWheelCarrier doesn't care if it carries wheels for trucks or busses or any other kind of wheel. Question is, what does it care about? What properties of any wheel does it need to do what it should do? Create an abstract superclass of Wheel (without any generics) or better yet, an interface IWheel and let VehicleWheel<TVehicle> inherit that, and VehicleWheelCarrier use just that. Commented Feb 22, 2018 at 7:14

2 Answers 2

3

You may add a non-generic base for wheel like this:

abstract class Vehicle {/**/}

class Truck : Vehicle {/**/}
class Bus : Vehicle {/**/}
//etc...

abstract class VehicleWheelBase { internal VehicleWheelBase() { } /*Non-generic definitions of Wheel*/}
abstract class VehicleWheel<TVehicle> : VehicleWheelBase where TVehicle : Vehicle {/**/}

class TruckWheel : VehicleWheel<Truck> {/**/}
class BusWheel : VehicleWheel<Bus> {/**/}

abstract class VehicleWheelCarrier<TWheel> : Vehicle where TWheel : VehicleWheelBase
Sign up to request clarification or add additional context in comments.

1 Comment

Great! This is what I was looking for! Thank you!
3

You would need a second generic parameter to define the needed type:

public abstract class VehicleWheelCarrier<TWheel, U> : Vehicle 
                                                     where TWheel:VehicleWheel<U> 
                                                     where U : Vehicle { }

EDIT: This will prevent you from making nonsensical constructs like:

class BusWheelCarrier : VehicleWheelCarrier<BusWheel, Truck>{ }

with the error:

There is no implicit reference conversion from BusWheel to VehicleWheel<Truck>.

But this will work:

class BusWheelCarrier : VehicleWheelCarrier<BusWheel, Bus>{ }

6 Comments

Is this only way? If I will make it that way, the following construct: class BusWheelCarrier : VehicleWheelCarrier<BusWheel, Truck> { /**/ } Will be valid, even if it doesn't have sense.
@JakubSzułakiewicz I don't quite understand your example. is it a new class that inherits from VehicleWheelCarrier ? can you post a complete example?
That's great (and correct) if you want very specialized VehicleWheelCarrier instances for every possible VehicleWheel and Vehicle combination. But I understood OP wanting to be able to carry "any type of wheel" with the same instance.
@JakubSzułakiewicz actually it will not be valid, if I understood you correctly. Have a look at my edit.
You're right. It resolves problem. But, solution provided by @Aly El-Haddad better fit my situation. Stii - thanks for help!
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.