IEnumerable as return type

前端 未结 10 2178
轮回少年
轮回少年 2020-12-01 10:41

Is there a problem with using IEnumerable as a return type? FxCop complains about returning List (it advises returning Coll

相关标签:
10条回答
  • 2020-12-01 10:59

    I think your own guidance is great -- if you are able to be more specific about what you're returning without a performance hit (you don't have to e.g. build a List out of your result), do so. But if your function legitimately doesn't know what type it's going to find, like if in some situations you'll be working with a List and in some with an Array, etc., then returning IEnumerable is the "best" you can do. Think of it as the "greatest common multiple" of everything you might want to return.

    0 讨论(0)
  • 2020-12-01 11:09

    One important aspect is that when you return a List<T> you are actual returning a reference. That makes it possible for a caller to manipulate your list. This is a common problem—for instance, a Business layer that returns a List<T> to a GUI layer.

    0 讨论(0)
  • 2020-12-01 11:11

    About your principle: "accept the least you can, but return the maximum".

    The key to managing the complexity of a large program is a technique called information hiding. If your method works by building a List<T>, it's not often necessary to reveal this fact by returning that type. If you do, then your callers may modify the list they get back. This removes your ability to do caching, or lazy iteration with yield return.

    So a better principle is for a function to follow is: "reveal as little as possible about how you work".

    0 讨论(0)
  • 2020-12-01 11:12

    No, IEnumerable<T> is a good thing to return here, since all you are promising is "a sequence of (typed) values". Ideal for LINQ etc, and perfectly usable.

    The caller can easily put this data into a list (or whatever) - especially with LINQ (ToList, ToArray, etc).

    This approach allows you to lazily spool back values, rather than having to buffer all the data. Definitely a goodie. I wrote-up another useful IEnumerable<T> trick the other day, too.

    0 讨论(0)
  • 2020-12-01 11:15

    I can't accept the chosen answer. There are ways of dealing with the scenario described but using a List or whatever else your using isn't one of them. The moment the IEnumerable is returned you have to assume that the caller might do a foreach. In that case it doesn't matter if the concrete type is List or spaghetti. In fact just indexing is a problem especially if items are removed.

    Any returned value is a snapshot. It may be the current contents of the IEnumerable in which case if it's cached it should be a clone of the cached copy; if it's supposed to be more dynamic (like the resuts of a sql query) then use yield return; however allowing the container to mutate at will and supplying methods like Count and indexer is a recipe for disaster in a multithreaded world. I haven't even gotten into the ability of the caller to call Add or Delete on a container your code is supposed to be in control of.

    Also returning a concrete type locks you into an implementation. Today internally you may be using a list. Tomorrow maybe you do become multithreaded and want to use a thread safe container or an array or a queue or the Values collection of a dictionary or the output of a Linq query. If you lock yourself into a concrete return type then you have to either change a bunch of code or do a conversions before returning.

    0 讨论(0)
  • 2020-12-01 11:17

    IEnumerable is fine by me but it has some drawbacks. The client has to enumerate to get the results. It has no way to check for Count etc. List is bad because you expose too much control; the client can add/remove etc. from it and that can be a bad thing. Collection seems the best compromomise, at least in FxCop's view. I allways use what seems appropiate in my context (eg. if i want to return a read only collection i expose collection as return type and return List.AsReadOnly() or IEnumerable for lazy evaluation through yield etc.). Take it on a case by case basis

    0 讨论(0)
提交回复
热议问题