Unfortunately, you can't. This isn't how generics are designed to work in C#. If you go with this pattern, you will be forced to always disambiguiate which interface version you wish to call Get()
on by casting repo
:
IFooBarRepository repo = SomeMethodThatGetsTheActualClass();
Foo foo = ((IRepository<Foo>)repo).Get(1);
which probably isn't what you want.
You could, of course, implement proxying methods in the implementation of IFooBarRepository
that return the right types ... but again, this may not be what you're looking for.
You can, however, create properties on IFooBarRepository
that improve the syntax thusly:
interface IFooBarRepository : IRepository<Foo>, IRepository<Bar>
{
IRepository<Foo> FooGetter { get; }
IRepository<Bar> BarGetter { get; }
}
Now you can write:
IFooBarRepository repo = SomeMethodThatGetsTheActualClass();
Foo foo = repo.FooGetter.Get(1);
Bar bar = repo.BarGetter.Get(2);
In general, it's desirable to avoid generic methods that don't accept as a formal parameters arguments of the types of the type parameters. In your case, you're trying to encode the semantics of repositories directly into the type system. You may be better off dividing this reponsibility into a type that expresses the behavior of the repository and a separate type that expresses the behavior of fetching objects.