I'm trying to do something like this:
public interface IRepository<T>
{
T Get<T>(int id);
}
public interface IFooBarRepository : IRepository<Foo>, IRepository<Bar>
{
}
IFooBarRepository repo = SomeMethodThatGetsTheActualClass();
Foo foo = repo.Get<Foo>(1);
I'm getting a warning:
Type parameter 'T' has the same name as the type parameter from outer type 'IRepository'
And an error:
The call is ambiguous between the following methods or properties: 'IRepository.Get(int)' and 'IRepository.Get(int)'
Any thoughts on how I can make this pattern work?
It is prohibited that a type implements or extends two different instantiations of the same interface. This is because the bridge method generation process cannot handle this situation.
Interface Type Constraint You can constrain the generic type by interface, thereby allowing only classes that implement that interface or classes that inherit from classes that implement the interface as the type parameter. The code below constrains a class to an interface.
C# allows that a single class can implement multiple interfaces at a time, and also define methods and variables in that interface.
To call the appropriate one, you'll need to make the compiler think of the expression in the appropriate way:
IFooBarRepository repo = SomeMethodThatGetsTheActualClass();
IRepository<Foo> fooRepo = repo;
Foo foo = fooRepo.Get(1);
Note that you could just cast it in one statement:
IFooBarRepository repo = SomeMethodThatGetsTheActualClass();
Foo foo = ((IRepository<Foo>)repo).Get(1);
... but that looks pretty ugly to me.
That deals with calling the method. Implementing both interfaces in one class is the next hurdle... because they'll have the same signature in terms of parameters. You'll have to implement at least one of them explicitly - and it might cause less confusion if you did both:
public class FooBarRepository : IFooBarRepository
{
Foo IRepository<Foo>.Get(int id)
{
return new Foo();
}
Bar IRepository<Bar>.Get(int id)
{
return new Bar();
}
}
EDIT: You'll also need to make Get
a non-generic method: currently you're trying to redeclare the type parameter T
in IRepository<T>.Get<T>
; you just want to use the existing type parameter of IRepository<T>
.
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