I have an interface like so...
public interface IAccountRepository : IDisposable {
IQueryable<Account> FindByUserId(int userId); //here, Resharper says "Return type can be IEnumerable<Account>"
}
But Resharper is suggesting me to change it to IEnumerable<Account> FindByUserId(int userId)
instead.
Why is that so? Wouldn't it force the entire objects to be loaded into memory? I thought it would be better to defer the execution until the object is really needed?
This is just a specific instance of a general rule.
If you are returning a type SomeClass
which implements an interface or inherits from another class, and in your entire solution you only use methods on the returned object which are in the base class/interface (so you don't use any methods declared in SomeClass
), ReSharper will suggest that you replace the type of the returned object with that of the base class/interface in order to make your code more general.
In this case, you are only using methods of the IEnumerable<T>
interface that IQueryable<T>
derives from.
Note also that this is just a suggestion, not a warning or an error. You can safely ignore this if you want to.
The answer is "no, BUT".
Casting it to IEnumerable does not force execution. Operators in the IEnumerable space (like the "Where" method) can still be lazily evaluated.
But there is some caveat here. If you, inside this method, start to use LINQ operators, then LINQ will choose the Enumerable LINQ operators like GroupBy (IEnumerable) instead of Queryable operators like GroupBy (IQueryable). Notice that they differ in their parameter list.
The effect of this is that your passed Lambda expression will be converted to a Func instead of an Expression> (note the difference in the parameter list of the two respective methods). So your lambda will not be an expression tree, which is what Queryable sources need in order to translate it to SQL (or similar) so that the query can be passed over the server and executed server side.
So, your query will be slower. Not because it will execute once you cast it, but because the whole datasource will be pulled over to the client once you start trying to get items off of it.
This is, of course, only if start using LINQ (attaching "Where" clauses or something) inside this method. If you don't, you're fine.
IQueryable
already inherits from IEnumerable
(MSDN), so any objection that you have to IEnumerable
will still be there. ReSharper is indicating that the method might as well be defined to return IEnumerable
even if all implementations return IQueryable
(if a call needed an IQueryable
instead of an IEnumerable
they can just call AsQueryable
too MSDN)
Also members of an IEnumerable
are only retrieved as they are enumerated, which means that e.g. even if each member was obtained by a separate web service call, those calls will only be made when the particular member is requested.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With