Requiring Inherited Types in Generic Constraints

A generic class can specify that its generic parameter must inherit a type.  However, there is no obvious way in general to prevent clients from passing the base type itself.

For example, take the following set of types:

abstract class Entity  { }

class Person : Entity { }
class Boat : Entity { }
class Car : Entity { }

class Repository<TEntity> where TEntity : Entity { }

This allows the type Repository<Entity>, which doesn’t make logical sense.

In this particular case, we could prevent that by changing the generic constraint to where TEntity : Entity, new().  Since the base Entity class is abstract, that would disallow a Repository<Entity>.  However,if the concrete entities also  don’t have default constructors, this wouldn’t work.  Similarly, had the base type been an interface, we could add a : class constraint.

There is an (somewhat) ugly hack that can be used to prevent parameterizations of the base class in arbitrary cases (as long as you control every type involved):

abstract class Entity  { }
interface IConcreteEntity { }    //Marker interface

class Person : Entity, IConcreteEntity { }
class Boat : Entity, IConcreteEntity { }
class Car : Entity, IConcreteEntity { }

class Repository<TEntity> 
      where TEntity : Entity, IConcreteEntity { }

Specifically, we can add a marker interface which is implemented by all concrete implementations of the base type.  We can then constrain a generic parameter to inherit both the base type and the marker interface.  Since the base class itself does implement the marker interface, it will not be valid as a parameter. 
Note that the marker interface must be implemented (perhaps indirectly) by every single concrete implementation.

3 comments:

This news is important. Kaya

I recommend you to read https://vpn-lab.com/expressvpn-review/ if you want to use VPN. Here you can read useful review

This post is really informative and you have posted such precious and informative article which gave me lot of information. I hope that you will keep it up and we will have more informative and helping news from you.
Play now friv oyunları for free!

Post a Comment