Reputation: 2287
I have a method as part of a generic class for use in the context of querying for a collection of objects where a boolean clause in an expression is met, and the result is ordered by some property on the object type.
The current method signature:
Task<T> GetFirstWhere(Expression<Func<T, bool>> whereExp, Expression<Func<T, DateTime>> orderByExp)
With an example implementation:
public async Task<T> GetFirstWhere(Expression<Func<T, bool>> whereExp, Expression<Func<T, DateTime>> orderByExp) {
return await _entities.Where(whereExp)
.OrderByDescending(orderByExp) // I would like to use any valid orderByExp type here
.FirstOrDefaultAsync();
}
For use in scenarios like:
var foundArticleTag = await _tags.GetFirstWhere(
tag => tag.Name == articleTag,
tag => tag.CreatedOn);
I would like orderByExp
function to use any valid type of property on T, rather than explicitly DateTime. I would prefer not to make the type dynamic, so that only valid types of properties on T might be used. I suppose reflection must be required for this, though I am not sure how to enforce the type constraint.
Upvotes: 0
Views: 145
Reputation: 142213
It seems that your method is part of generic type of T
, you can make your method generic also (accepting another generic type parameter for ordering expression):
Task<T> GetFirstWhere<TOrder>(
Expression<Func<T, bool>> whereExp,
Expression<Func<T, TOrder>> orderByExp);
That will require adding the generic parameter to the example implementation:
public async Task<T> GetFirstWhere<TOrder>(Expression<Func<T, bool>> whereExp, Expression<Func<T, TOrder>> orderByExp) {
return await _entities.Where(whereExp)
.OrderByDescending(orderByExp) // I would like to use any valid orderByExp type here
.FirstOrDefaultAsync();
}
And usage should remain untouched, because the compiler should be able to infer generic TOrder
type parameter from the usage.
Upvotes: 3
Reputation: 15151
You can use as many as generic parameters as you want, so this can be easily extended for a second generic:
public async Task<T> GetFirstWhere<T, O>(Expression<Func<T, bool>> whereExp, Expression<Func<T, O>> orderByExp) {
return await _entities.Where(whereExp)
.OrderByDescending(orderByExp)
.FirstOrDefaultAsync();
}
Upvotes: 2