Let's assume I have:
- A generic method
Get<T> - A few interfaces
IEntity,IValue - A few classes that respectively implements those interfaces ex:
Entity->IEntity,Value->IValueetc.
=> Is there a way for the Get<T> method to allow the interfaces only as generic Types?
Get<IEntity>(42); //Allowed
Get<Entity>(42); //Compiler error
My current solution looks like this:
- A generic method
Get<T>with a Type constraintwhere T: IPersistable(to prevent most of the types to be passed as a parameter) - The interfaces implement
IPersistable
The function actively checks the type:
public T Get<T>(long id) where T : IPersistable
{
if (typeof (T) == typeof (IEntity))
return (T) EntityDao.Get(id);
if (typeof (T) == typeof (IValue))
return (T) ValueDao.Get(id);
//...
throw new TechnicalException("Type not supported");
}
=> The problem are:
- It is not clean... I could live with that since there are only very few types to check from
- The signature does not match what the function really does. It allows an
IPersistablein, but not really <- that really bugs me :(
Edit: I'm considering such constraints to avoid surpopulation of my class.
I have something like 8 or 9 generic methods in that class that all pretty much work this way. The intuitive way of doing would be as @DanielHilgarth suggested to have 1 method per type only. The methods currently can be called with 4 or 5 types only. But still, that would mean 32-40 methods in that class.
If possible I'd like to avoid that.
Edit2: the need for preventing "real" classes to be called comes from a covariance/contravariance problem. The EntityDao and ValueDao Get<T> methods return IEntity and IValue objects. What works fine when I query for a single object fails when I call for a collection in a GetAll<T> methods since I cannot cast an IEnumerable<IValue> in an IEnumerable<Value>.
I just noticed this answer from @JonSkeets about casting of lists. That could be a workaround...