Resharper, "The return type may be IEnumerable ...", but why?

I have such an interface ...

public interface IAccountRepository : IDisposable { IQueryable<Account> FindByUserId(int userId); //here, Resharper says "Return type can be IEnumerable<Account>" } 

But Resharper offers me to change it to IEnumerable<Account> FindByUserId(int userId) .

Why is this so? Wouldn't that make all objects load into memory? I thought it would be better to defer execution until the object is needed?

+6
source share
3 answers

This is just a concrete example of a general rule.

If you return a SomeClass type that implements an interface or inherits from another class, and in all your decision you use only the return object methods that are in the base class / interface (therefore, you do not use any methods declared in SomeClass ), ReSharper will suggest replacing return type to base class / interface type to make your code more general.

In this case, you only use the IEnumerable<T> interface methods from which IQueryable<T> comes from.

Please also note that this is just a suggestion, not a warning or error. You can safely ignore this if you want.

+8
source

The answer is "no, BUT ."

Passing it to IEnumerable does not lead to enforcement. Operators in the IEnumerable space (for example, the Where method) can still be evaluated lazily.

But there are some warnings here. If you start using LINQ statements inside this method, then LINQ will select Enumerable LINQ statements, such as GroupBy (IEnumerable), instead of Queryable statements, such as GroupBy (IQueryable) . Note that they differ in the parameter list.

The effect of this is that your passed Lambda expression will be converted to Func instead of Expression> (note the difference in the parameter list of the two corresponding methods). Thus, your lambda will not be an expression tree, and this is what Queryable sources need to translate it to SQL (or similar) so that the query can be transmitted across the server and executed on the server side.

So your request will be slower. Not because it will be executed after you pronounce it, but because the entire data source will be redirected to the client as soon as you start trying to remove elements from it.

This, of course, is only if you start using LINQ (attach "Where" or something) inside this method. If you do not, you are fine.

+6
source

IQueryable already inherits from IEnumerable ( MSDN ), so any objection you have on IEnumerable will still be there. ReSharper points out that the method can also be defined to return IEnumerable , even if all implementations return IQueryable (if the call requires IQueryable instead of IEnumerable , they can simply call AsQueryable also MSDN )

IEnumerable members are also retrieved only as they are enumerated, which means that, for example, even if each member was received by a separate web service call, these calls will only be made when a specific member is requested.

+1
source

Source: https://habr.com/ru/post/950440/


All Articles