Generally, it's better to return IEnumerable<T>
, as long as that has everything the caller needs.
IEnumerable<T>
is foreachable, which is all that's needed for many consumers. It's also read-only, which is often a good thing -- it means you can sometimes optimize by returning your actual backing collection, without worrying too much about someone modifying it without telling you.
However, if the consumer needs methods that aren't on IEnumerable<T>
, then IList<T>
might make more sense. For example, the caller may want to call Contains
, which isn't on IEnumerable<T>
. Or the caller may want to index into the list, rather than iterating it from start to finish.
But you can do Contains and indexing on IEnumerable<T>
too, via LINQ's Contains and ElementAt extension methods. So there's a question of degree here. If the caller only needs to ask one question that isn't available on IEnumerable<T>
, like "is this empty", then return an IEnumerable<T>
and use the Any extension method. But if the caller uses IList<T>
operations extensively, return IList<T>
.