tags:

views:

283

answers:

2

Just I am maintaining a project.It has been written in C# 3.0.Some Implementations return collection as IQueryable.

like

List<BookData> data = new List<BookData>();
   ...

   data.Add(new BookData { ID = "P001", BookTitle = "C# in Depth" });
   data.Add(new BookData { ID = "P002", BookTitle = "F# in Depth" });

    public IQueryable GetBooks()
    {
        return data.AsQueryable();
    }

The code would have return the collection list. What is the special in returning them as AsQueryable ?

A: 

Without using reflection or casting the returned object, the only methods that are available on the returned collection are those defined by the interface. This would be one way of restricting some types of access to the collection -- for instance, IQueryable doesn't have an add method. Unfortunately this isn't safe in the face of a "hostile" user of your code. If you truly need the collection to be inviolable, a better way is to return a read-only copy of the collection rather than the actual collection cast as a different interface.

Note that I'm assuming a List, as in your example, or some other class that actually implements IQueryable natively. In this case the source object is returned. If the underlying object doesn't implement IQueryable then an IQueryable is returned that proxies the calls to the underlying IEnumerable.

tvanfosson
This is not related to my post. Do we get any benefit in using IQueryable?
James
You get some obscurity from returning it as IQueryable. In this case `List<T>` already implements IQueryable so what is happening is that you are essentially hiding some of its methods, restricting the set to only those defined by IQueryable. Because it's non-generic, you're also losing the strong-typing of the underlying container.
tvanfosson
A: 

AsQueryable doesn't really do anything when invoked on a plain old collection like a List<T>, so the answer probably depends on another part of the codebase. For example, someone might have defined a GetBooks method to take an IQueryable<Book>, with the intent that the GetBooks method would perform any ordering or filtering in the database via a LINQ provider. But the code you're looking at constructs the set of books as a collection (a List<Book>), not a query. In order for the result to be passed the hypothetical GetBooks method, the collection has to be wrapped in an IQueryable<Book>, even though that wrapper is just going to delegate straight back to the LINQ to Objects methods (rather than translating the GetBooks operations to SQL queries).

Or perhaps the class you're looking at implements an interface where the method you're looking at is declared as returning IQueryable<Book> (for similar reasons to above), so your code is having to wrap the List<Book> to remain compatible with the interface signature.

itowlson