I've written an extension method on IQueryable which returns the same type of IQueryable, just filtered a bit. Let's say it's something like that:
public static IEnumerable<T> Foo<T>(this IEnumerable<T> source, int? howmany = null)
{
if (howmany.HasValue)
return source.Take(howmany.Value);
return source;
}
calling the above method is as simple as someLinqResult.Foo(2)
I need other method that will return instance of other generic class, but with other base class (not the same as source T
above).
So, here's the code, let's assume this method is supposed to return a list of given type (other than the input type which IQueryable has!) but the same length [the actual problem is about transforming NHibernate query results, but it doesn't matter):
public static List<TTarget> Bar<TTarget,TSource>(this IEnumerable<TSource> source)
{
return new List<TTarget>(source.Count());
}
now, given that the strLinqResult
is IQueryable<string>
, I need to call it strLinqResult.Bar<int,string>();
.
The point is I have to pass both types, even though the first one is already known as I'm calling the method on already defined IQuerable
.
Since it was enough to call Foo(2)
and not Foo<string>(2)
I thought the compiler is able to "pass/guess" the type automatically.
So why do I need to call the second method Bar<int,string>();
and not just Bar<int>()
?
the actual code:
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
is kind of Foo
method from the example code - it just applies pagination & ordering params available in ListRequest
object.
Items
is a public List<T> Items
in a class ListResponse<T>
.
TranslateTo
is a method from ServiceStack.
The above method called on IQueryable<T>
returned by NHibernate (T is Domain Model) takes the request parameters (ordering, pagination), applies them, and then transforms the results list from DomainModel
to DTO Object of type TResponse
. The list is then wrapped in a generic response class (generic, so it is reusable for many DTO types)