Honestly, it is much more code to use loop with non-local control like break, continue etc. (variable initialization, append, variable mutation in loops…) than just calling a collect function (which I assume just means to_list). In the above example, in most programming language I know, you don’t even need to collect the result into a list.
Not to mention, large loops with non-local control is a breeding ground for spegatti code. Because you no longer have a consistent exit point to the loop, thus making the semantics hard o reason about.
In many languages, there are type class / trait / interfaces (whatever you want to call them) that allows lazy structures to share the same API as strict ones.
as far as I know, C# don’t have proper ergonomic monadic bind as in F# (computation expression), Haskell (do expression), and Ocaml (let*), but I could be wrong.