Generics and casting – cannot cast inherited class to base class

RepositoryBase<EntityBase> is not a base class of MyEntityRepository. You’re looking for generic variance which exists in C# to a limited extent, but wouldn’t apply here.

Suppose your RepositoryBase<T> class had a method like this:

void Add(T entity) { ... }

Now consider:

MyEntityRepository myEntityRepo = GetMyEntityRepo(); // whatever
RepositoryBase<EntityBase> baseRepo = (RepositoryBase<EntityBase>)myEntityRepo; 
baseRepo.Add(new OtherEntity(...));

Now you’ve added a different kind of entity to a MyEntityRepository… and that can’t be right.

Basically, generic variance is only safe in certain situations. In particular generic covariance (which is what you’re describing here) is only safe when you only ever get values “out” of the API; generic contravariance (which works the other way round) is only safe when you only ever put values “into” the API (e.g. a general comparison which can compare any two shapes by area can be considered as a comparison of squares).

In C# 4 this is available for generic interfaces and generic delegates, not classes – and only with reference types. See MSDN for further information, read <plug>read C# in Depth, 2nd edition, chapter 13</plug> or Eric Lippert’s blog series on the topic. Also, I gave a one hour talk about this at NDC in July 2010 – the video is available here.

Leave a Comment