IQueryable的通用扩展方法
本文关键字:扩展 方法 IQueryable | 更新日期: 2023-09-27 18:18:50
我在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
是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
是class ListResponse<T>
中的public List<T> Items
。
TranslateTo
是一个来自ServiceStack的方法。
在NHibernate (T是域模型)返回的IQueryable<T>
上调用的上述方法接受请求参数(排序,分页),应用它们,然后将结果列表从DomainModel
转换为TResponse
类型的DTO对象。然后将列表包装在泛型响应类中(泛型,因此它可用于许多DTO类型)
如果我正确理解您的问题,您正在尝试输入尽可能少的参数。这是不可能的。要么全有,要么全无,它可以自己解决所有问题。
只指定一些的问题是,您将能够引入一个带有1 less类型参数的类似方法,并且现在将破坏实现。
你能不能也分享一下你最初的问题?也许可以让编译器找出一些其他的方式?