I'm fairly new to generics so I wonder if somebody can explain the following problem I'm having. In virtually all my controllers in an ASP.NET MVC application I need to return a filtered list (to populate a JqGrid as it happens where the user will have specified certain filtering criteria). Each controllers list method will return a different IQueryable list so I set about creating a generic method to handle this.

While I was creating my method I defined it in a specific controller. Everything compiled and I got the results I expected. Because I want to call this method from all my controllers I assumed I could simply create another static class, put the method in there and then call that method from all my controllers. But if I try to move the method to anywhere else other than the controller thats calling it, the compiler complains about the last line of the method with the following error:

The type arguments for method System.Linq.Queryable.Where<TSource>(System.Linq.IQueryable<TSource>, System.Linq.Expressions.Expression<System.Func<TSource,bool>>) cannot be inferred from the usage. Try specifying the type arguments explicitly.

public static IQueryable<T> FilteredList<T>(IQueryable<T> list, string filters)
     var qb = new QueryBuilder<T>();
     var whereClause = qb.BuildWhereClause(filters);
     return list.Where(whereClause);

I've tried list<T>.Where(whereClause) and list.Where<T>(whereClause) and just about every other combination, can anyone explain to me where I'm going wrong.


IQueryable does not have a Where method on it. So you need IQueryable which means you must specify the type argument in method declaration:

public static IQueryable<T> FilteredList<T>(IQueryable<T> list, string filters)
Calling `Where` on an `IQueryable` is perfectly valid. There is an appropriate extension method defined on `System.Linq.Queryable.`
-1 IQueryable has a Where: http://msdn.microsoft.com/en-us/library/bb919081.aspx
Abhijeet Patel
+1  A: 

That would suggest that your BuildWhereClause method isn't returning the appropriate type.

The compiler is trying to infer the type of TSource from both list and whereClause. Now whereClause should be an Expression<Func<T, bool>> but I suspect it's not. Hover over the var in the declaration of whereClause to find out what it actually is. I wouldn't recommend using var when the return type isn't obvious.

Jon Skeet
Jon, thanks for your reply, as you can see from my other post BuildWhereClause is actually returning a string because I'm using Dynamic Linq - all working correctly now. Good point about not using var for non obvious return types, I'll try to be more explicit in the future. P.S. Loving your c# in depth book by the way.
Simon Lomax