Reputation: 9500
Is it possible to have an implementing class define the generic parameter for an interface? Or, in other words, derive the generic parameter from the implementation?
In the example below, I want to be able to use the Repository interface regardless of the Entity type Id.
1 class Entity<T> // where id is either an int or Guid
2 {
3 public T Id { get; set; }
4 }
5 interface IRepository<T>
6 {
7 IEnumerable<Entity<T>> ListAll();
8 }
9 class GuidRepository : IRepository<Guid> // this repo deals with Guid type entities
10 {
11 public Entity<Guid> ListAll()
12 {
13 // list all entities
14 }
15 }
16 class Program
17 {
18 private IRepository GetRepository(int someCriteria)
19 {
20 switch (someCriteria)
21 {
22 case 1:
23 return new GuidRepository();
24 ...
25 }
26 }
27 static void Main(string[] args)
28 {
29 Program p = new Program();
30 IRepository repo = p.GetRepository(1);
31 var list = repo.ListAll();
32 }
33 }
As the code stands now, the compiler complains at line 18 stating:
Using the generic type requires 1 type arguments
In my real project, the method calling GetRepository is an MVC controller action and therefore unable to determine the type parameter at the line 16 level.
Upvotes: 0
Views: 1322
Reputation: 6531
Can you treat a GenericClass<T>
polymorphically with GenericClass<Y>
where T
and Y
are different classes?
No. And that's kind of the point. You want type safety between T
and the Y
, which is what Generics offer.
I notice you say you can print both to console, which is true because both have ToString()
methods. If you want a collection of objects that have this ability you want GenericClass<object>
.
Mixing IGenericInterface<N>
and IGenericInterface<M>
under IGenericInterface<O>
when N : O
and M : O
is called Covariance and is a bit complex, it's a interface thing that is implemented when creating the interface.
Upvotes: 3