Question

I have the following classes:

public abstract class ThingBase { }

public class ThingA : ThingBase { }

And the following generic class:

public class ThingOwner<ThingType> where ThingType : ThingBase { }

I would like to create a ThingOwner instance like below:

ThingOwner<ThingBase> thingOwner = new ThingOwner<ThingA>();

With this code, I get the following error: "Cannot implicitly convert type 'ThingOwner(ThingA)' to 'ThingOwner(ThingBase)'".

I can't figure how to make it work. I know there are lots of existing discussions about generic classes and inheritance but I tried pretty much everything and I couldn't find a solution that worked for me.

Thanks!

Was it helpful?

Solution

You should make use of covariance for generic types introduced in C# 4.0. For this to work you need to use an interface instead of a class:

public interface IThingOwner<out ThingType> where ThingType : ThingBase { }

public class ThingOwner<ThingType> : IThingOwner<ThingType>
    where ThingType : ThingBase
{

}


IThingOwner<ThingBase> thingOwner = new ThingOwner<ThingA>();

OTHER TIPS

Covariance/contravariance is only supported for interfaces. If you need classes, then only these can work:

ThingOwner<ThingBase> thingOwner = new ThingOwner<ThingBase>();
ThingOwner<ThingA> thingOwner = new ThingOwner<ThingA>();

In addition to the above answers some explanation. While your question can be understood, think of the following:

State you have a derived class that accepts a type parameter ClassA. In the ThingOwner<ClassA> it is only allowed to add an instance of a class that is or derives from ClassA. When you cast that to ThingOwner<BaseClass> it is suddenly allowed to add an instance of ClassB which also derived from BaseClass. This can harm your program and is actually wrong. This was why they invented generics in the first place.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top