获取泛型类型的属性类型以在表达式中使用

问题描述 投票:0回答:2

我有一个方法作为泛型类的一部分,用于查询满足表达式中布尔子句的对象集合的上下文,并且结果按对象类型的某些属性排序。

当前方法签名:

Task<T> GetFirstWhere(Expression<Func<T, bool>> whereExp, Expression<Func<T, DateTime>> orderByExp)

通过示例实现:

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();
}

适用于以下场景:

var foundArticleTag = await _tags.GetFirstWhere(
    tag => tag.Name == articleTag, 
    tag => tag.CreatedOn);

我希望

orderByExp
函数使用 T 上的任何有效类型的属性,而不是显式的 DateTime。我不想使类型动态化,这样就只能使用 T 上的有效类型的属性。我想这必须需要反射,尽管我不确定如何强制执行类型约束。

c# .net asp.net-core
2个回答
3
投票

看来你的方法是泛型类型的一部分

T
,你也可以使你的方法泛型(接受另一个泛型类型参数用于排序表达式):

Task<T> GetFirstWhere<TOrder>(
    Expression<Func<T, bool>> whereExp, 
    Expression<Func<T, TOrder>> orderByExp);

这需要将通用参数添加到示例实现中:

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();
} 

并且用法应该保持不变,因为编译器应该能够从用法推断通用

TOrder
类型参数。


2
投票

您可以根据需要使用任意数量的泛型参数,因此可以轻松扩展第二个泛型:

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();
}
© www.soinside.com 2019 - 2024. All rights reserved.