I have an interface (which is used by repositories) that has this member:
T FindById<T, TId>(TId id)
where T : class, IEntity<TId>
where TId : IEquatable<TId>;
This allows the caller to specify an entity type (T
) and the type of it's Id
field (TId
). The implementor of this interface would then find the entities of type T
and use the id
parameter to filter them according to their id (which is defined on IEntity<TId>
).
Currently I'm calling it like this:
int id = 123;
var myApproval = PartsDC.FindById<Approval, int>(id);
Ideally I'd like to do this:
int id = 123;
var myApproval = PartsDC.FindById<Approval>(id);
I've read the answers for this question:
Partial generic type inference possible in C#?
I understand I can't get the syntax I want, but can get close. I can't quite get it setup right in my case though because of my generic parameter constraints.
Here's what I have so far:
public class FindIdWrapper<T> where T : class
{
public readonly IDataContext InvokeOn;
public FindIdWrapper(IDataContext invokeOn)
{
InvokeOn = invokeOn;
}
T ById<TId>(TId id) where TId : IEquatable<TId>
{
return InvokeOn.FindById<T, TId>(id);
}
}
public static class DataContextExtensions
{
public static FindIdWrapper<T> Find<T>(this IDataContext dataContext) where T : class, IEntity
{
return new FindIdWrapper<T>(dataContext);
}
}
The compilation error I get is:
The type 'T' cannot be used as type parameter 'T' in the generic type or method 'PartsLegislation.Repository.IDataContext.FindById<T,TId>(TId)'. There is no implicit reference conversion from 'T' to 'PartsLegislation.Repository.IEntity<TId>'.
I understand what it's saying because the T
in my wrapper class is only constrained to be a reference type, but the FindById
function wants it to be IEntity<TId>
, but I can't do that as the TId
is in the method (otherwise I'm back at square one).
How can I get around this issue (or can't I)?
See Question&Answers more detail:
os