我在 IQueryable 上编写了一个扩展方法,它返回相同类型的 IQueryable,只是过滤了一下。假设它是这样的:
public static IEnumerable<T> Foo<T>(this IEnumerable<T> source, int? howmany = null)
{
if (howmany.HasValue)
return source.Take(howmany.Value);
return source;
}
调用上述方法很简单someLinqResult.Foo(2)
我需要其他方法来返回其他泛型类的实例,但使用其他基类(与T
上面的源不同)。所以,这是代码,让我们假设这个方法应该返回一个给定类型的列表(除了 IQueryable 具有的输入类型!)但长度相同[实际问题是关于转换 NHibernate 查询结果,但它没有事情):
public static List<TTarget> Bar<TTarget,TSource>(this IEnumerable<TSource> source)
{
return new List<TTarget>(source.Count());
}
现在,鉴于strLinqResult
is IQueryable<string>
,我需要调用它strLinqResult.Bar<int,string>();
。
关键是我必须通过这两种类型,即使第一种类型已经知道,因为我正在调用已经定义的方法IQuerable
。
因为它足以调用Foo(2)
,而不是 Foo<string>(2)
我认为编译器能够自动“传递/猜测”类型。
那么为什么我需要调用第二种方法Bar<int,string>();
而不仅仅是Bar<int>()
?
实际代码:
public static ListResponse<TResponse>
BuildListResponse<T,TResponse>(this IQueryable<T> iq, ListRequest request)
where TResponse: new()
{
var result = iq.ApplyListRequestParams(request).ToList().ConvertAll(x => x.TranslateTo<TResponse>());
var tcount = iq.Count();
return new ListResponse<TResponse> {
Items = result,
_TotalCount = tcount,
_PageNumber = request._PageNumber ?? 1,
};
}
ApplyListRequestParams
是Foo
示例代码中的一种方法 - 它仅应用ListRequest
对象中可用的分页和排序参数。
Items
是一个public List<T> Items
在一个class ListResponse<T>
。
TranslateTo
是 ServiceStack 中的一种方法。
NHibernate(T 是域模型)返回的上述调用方法IQueryable<T>
获取请求参数(排序、分页),应用它们,然后将结果列表从DomainModel
类型转换为 DTO 对象TResponse
。然后将该列表包装在通用响应类中(通用,因此它可用于许多 DTO 类型)