Your final paragraph is not exactly wrong, but isn't quite right either.
IEnumerable<T>
is an interface that (pretty much) every collection in C# implements, List<T>
being a prime example. In the OO lingo, a List<T>
"is-an" IEnumerable<T>
, which is why lists work with LINQ. Same goes for arrays. Most common implementations of IEnumerable<T>
are collections and do in fact store data, but some implementations can generate elements as you iterate through them - yield return
being syntactic sugar that makes writing these sorts of enumerables (and their associated enumerators) easier.