IQueryable上的泛型扩展方法<t> </t>

时间:2013-06-16 19:46:06

标签: c# generics extension-methods

我在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,
            };
    }

ApplyListRequestParams是一种来自示例代码的Foo方法 - 它只是应用了分页&amp;订购ListRequest对象中可用的参数。

Itemspublic List<T> Items中的class ListResponse<T>

TranslateTo是ServiceStack的一种方法。

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

1 个答案:

答案 0 :(得分:3)

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

仅指定一些的问题是,您将能够使用1 less type参数引入类似的方法,现在将破坏实现。

但是你有机会分享你原来的问题吗?可能让编译器以其他方式解决这个问题吗?