4 ms·
But if you're ToListing it, your return type might as well just be List, not IEnumerable (or IQueryable). I feel that by declaring your return type as IEnumera
by upthedale 14y ago
But if you're ToListing it, your return type might as well just be List, not IEnumerable (or IQueryable).
I feel that by declaring your return type as IEnumerable, you're implicitly saying to any caller that the return object is something that can iterate (and potentially generate) through results when requested, and so care should be taken with its use (to avoid getting multiple IEnumerator objects, and iterating unnecessarily).
As I've said elsewhere, this functionality should be embraced.
One of the ways the caller might prevent iterating unnecessarily may be to call ToList or ToArray. Alternatively, they might structure their calling code better. Either way, it should be the caller's choice, instead of being imposed by the underlying method.
- bunderbunder 14y agoBut if you're ToListing it, your return type might as well just be List, not IEnumerable Perhaps, it really depends. One nice advantage that returning IEnumerable<T> has over returning List<T> is that it gives better flexibility and maintainability. If you return List<T>, you're tying yourself to that specific class now and forever. Any change will be a breaking change. If you return IEnumerable<T>, all you're guaranteeing is that you'll return something that the caller can enumerate over to get their data. Meaning if you later discover that you have some compelling reason to switch to using a HashSet<T> internally, and that it would also be most convenient if you could just pass back that HashSet<T>, well, there's nothing to stop you. You don't get that flexibility by typing your return value as List<T> because you've tied yourself to that specific class. You also don't get that flexibility by passing back IList<T>. IList<T> defines an ordered, positionally-indexed collection, and hashes are not that. ICollection<T> might work, but it defines an interface for a mutable collection, which might also be a restriction you don't want to commit to now and forever. So in general it's best to pass back the most flexible type you can. Partially because YAGNI, but mostly because trying to create a pit of success for your users doesn't mean you can't also try to create a pit of success for yourself as well. (Forgot to mention - the semantics that you're claiming for IEnumerable doesn't really line up with how it's actually used. IEnumerable has been around since .NET 1.1, and IEnumerable<T> has been around since .NET 2.0. There were years and years where IEnumerable simply defined an object that could be enumerated before LINQ came on the scene and introduced us to ubiquitous examples of lazily-generated IEnumerables, or introduced all these useful extension methods that take IEnumerable<T> and return a lazily-generated IEnumerable<T>.)
- upthedale 14y agoDefinitely. Should have left that first line out, as it wasn't what I was trying to argue. The rest of my point still stands. Edit: I see you've appended to your comment. The problem is you could always have lazily-evaluated IEnumerables by implementing an IEnumerator. It was just a pain in the arse until C#2 brought us generator support through the yield keyword. This was long before Linq came along. Edit2: > There were years and years where IEnumerable simply defined an object that could be enumerated... Which is my point exactly. And nothing has changed with IEnumerable (generics excluded). It certainly doesn't say that all the objects are already held in-memory (as enforcing ToList would do). By returning an IEnumerable, you're just saying here's an object that can produce you a sequence of results. In a public API, it should be documented (at least some vague allusion to) whether this will be produced by trivially pulling them out of an in-memory list, or whether something a bit more clever is going on, as there'll certainly be occasions where streaming the results through a generator is more desirable than holding them all in memory.