Reputation: 1005
I am looking at some covariance/contravariance stuff, I have a much wider question but it all boils down to this:
GenericRepository<BaseEntity> repo = new GenericRepository<ProductStyle>(context);
This doesn't work, even though BaseEntity is the parent abstract class of ProductStyle, is there a way of achieving this?
Upvotes: 8
Views: 146
Reputation: 28701
I'm just wondering if something like this would also be useful -- using a restriction on the definition of your GenericRepository limiting the base type that T
can be:
void Main()
{
var repo = new GenericRepository<ProductStyle>(new ProductStyle());
Console.WriteLine(repo.ToString()); //just output something to make sure it works...
}
// Define other methods and classes here
public class GenericRepository<T> where T : BaseEntity {
private readonly T _inst;
public GenericRepository(T inst){
_inst = inst;
_inst.DoSomething();
}
}
public class BaseEntity {
public Int32 Id {get;set;}
public virtual void DoSomething() { Console.WriteLine("Hello"); }
}
public class ProductStyle : BaseEntity {
}
So if you have a GetRepo<T>
method, that method could return a GenericRepository of T, and you're assured that T
is a child of BaseEntity
.
Upvotes: 0
Reputation: 1062705
The only way of doing that is with an out
generic restriction (which will make it hard to save objects, but fine to retrieve them), on an interface
(not a class
). If you have:
interface IGenericRepository<out T> {...}
then an IGenericRepository<ProductStyle>
can be assigned to a variable of type IGenericRepository<BaseEntity>
, since all ProductStyle
are also BaseEntity
, and we have restricted ourselves to covariant / out
usage:
IGenericRepository<BaseEntity> tmp = GetRepo<ProductStyle>(context);
// note that the right-hand-side returns IGenericRepository<ProductStyle>
...
private IGenericRepository<T> GetRepo(...) {...}
Note, however, that this covariant / out
usage makes it impossible to do things like:
interface IGenericRepository<out T>
{
T Get(int id); // this is fine, but:
void Save(T value); // does not compile; this is not covariantly valid
}
Upvotes: 6