简体   繁体   English

获取泛型类型的属性类型以用于表达式

[英]Get property types of generic type for use in expression

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.我有一个方法作为通用 class 的一部分,用于查询满足表达式中的 boolean 子句的对象集合的上下文,并且结果由 ZA8CFDE6331BD59EB2AC96F8911C4B66 类型的某些属性排序。

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.我希望orderByExp function 在 T 上使用任何有效类型的属性,而不是明确的 DateTime。 I would prefer not to make the type dynamic, so that only valid types of properties on T might be used.我不希望使类型动态化,因此只能使用 T 上的有效属性类型。 I suppose reflection must be required for this, though I am not sure how to enforce the type constraint.我想这必须需要反射,尽管我不确定如何强制执行类型约束。

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):看来您的方法是T泛型类型的一部分,您也可以使您的方法泛型(接受另一个泛型类型参数用于排序表达式):

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, cause compiler should be able to infer generic TOrder type parameter from the usage.并且用法应该保持不变,因为编译器应该能够从用法中推断出通用的TOrder类型参数。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM