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):

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.