Let's say there are these generic types in C#:
class Entity<KeyType>
{
public KeyType Id { get; private set; }
...
}
interface IRepository<KeyType, EntityType> where EntityType : Entity<KeyType>
{
EntityType Get(KeyType id);
...
}
and these concrete types:
class Person : Entity<int> { ... }
interface IPersonRepository : IRepository<int, Person> { ... }
Now the definition of PersonRepository
is redundant: the fact that the KeyType
of Person
is int
is stated explicitly, although it can be deduced from the fact that Person
is a subtype of Entity<int>
.
It would be nice to be able to define IPersonRepository
like this:
interface IPersonRepository : IRepository<Person> { ... }
and let the compiler figure out that the KeyType
is int
. Is it possible?
No, C#'s type system is not sufficiently advanced to express what you want. The feature needed is called higher kinded type which are often found in strongly typed functional languages (Haskell, OCaml, Scala).
Working our way back, you want to be able to write
interface IRepository<EntityType<EntityKey>> {
EntityType<EntityKey> Get(KeyType id);
}
interface PersonRepository : IRepository<Person> {
Person Get(Int id);
}
but in C# there is no way to express the kind EntityType or, in other words, that the type parameter has some generic parameter and use that generic parameter in your code.
Side note: The Repository pattern is Evil and must die in a fire.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With