IQueryable in IEnumerable

Apr 29, 2013 at 2:01 PM

In the documentation of Project silk it says following:

"In Mileage Stats, the implementation of the iReminderRepository calls Tolist before returning the iEnumerable<T>. This is to ensure that the query is executed inside the repository. If Tolist was not called, then the repository would return an iQueryable<T> and the database would not be accessed until something iterated over the iQueryable<T> object."

A code expample:
 public IEnumerable<Reminder> GetRemindersForVehicle(int vehicleId)
            return this.GetDbSet<Reminder>()
                .Where(v => v.VehicleId == vehicleId)
Does that mean that even though the result is returned like IEnumerable, this would just be a container for a IQueryable, and if ToList() would not be called than one could be making calls on the IEnumerable as if it was a IQueryable?

Is this really right? It sounds wrong to me. If you where to make calls on the IEnumerable<Reminder>, that is returned if ToList isn't called, it would be the extension methods of IEnumerable that would be used and not IQueryable.

How can they clame that the function is returning a iQueryable<T> if ToList is not called, how is that possible?

It would be right if the method was returning a iQueryable<T> but it dosen't.
Apr 29, 2013 at 8:14 PM

Based on my understanding, it is as the documentation says. This is due to a quality of the object oriented programming languages named Polymorphism.

Basically, the IQueryable interface inherits from the IEnumerable interface. This allows you to sent a reference of type IEnumerable to an IQueryable implementation, return an IQueryable "as it was" an IEnumerable, etc. Hence, without the ToList invocation (which returns a List which is an IEnumerable implementation), an IQueryable would be returned instead "masked" as an IEnumerable.

When storing an IQueryable using a reference of type IEnumerable you can invoke its methods like you would on an IEnumerable but the logic that will be executed is the one defined in the IQueryable implementation, e. i. the behavior of the object will still be the one of an IQueryable.
The same applies to the IEnumerable extension methods because, basically, an extension method is an static method that uses the original methods of the object to work.

You can find more information about Polimorphism in the following MSDN article:

Damian Cherubini