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

现在,假定strLinqResultIQueryable<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,
            };
    }

ApplyListRequestParamsFoo方法的一种从示例代码-它只是应用分页&ListRequest对象中可用的排序参数。

Itemsclass ListResponse<T>中的public List<T> Items

TranslateTo是一个来自ServiceStack的方法。

在NHibernate (T是域模型)返回的IQueryable<T>上调用的上述方法接受请求参数(排序,分页),应用它们,然后将结果列表从DomainModel转换为TResponse类型的DTO对象。然后将列表包装在泛型响应类中(泛型,因此它可用于许多DTO类型)

IQueryable<T>的通用扩展方法

如果我正确理解您的问题,您正在尝试输入尽可能少的参数。这是不可能的。要么全有,要么全无,它可以自己解决所有问题。

只指定一些的问题是,您将能够引入一个带有1 less类型参数的类似方法,并且现在将破坏实现。

你能不能也分享一下你最初的问题?也许可以让编译器找出一些其他的方式?