What practices can safeguard against unexpected deferred execution with IEnumerable<T> as argument?
As you can see both the functions take
IEnumerable<>
, but the caller wouldn't know how the functions react.
That's simply a matter of documentation. Look at the documentation for DistinctBy
in MoreLINQ, which includes:
This operator uses deferred execution and streams the results, although a set of already-seen keys is retained. If a key is seen multiple times, only the first element with that key is returned.
Yes, it's important to know what a member does before you use it, and for things accepting/returning any kind of collection, there are various important things to know:
- Will the collection be read immediately, or deferred?
- Will the collection be streamed while results are returned?
- If the declared collection type accepted is mutable, will the method try to mutate it?
- If the declared collection type returned is mutable, will it actually be a mutable implementation?
- Will the collection returned be changed by other actions (e.g. is it a read-only view on a collection which may be modified within the class)
- Is
null
an acceptable input value? - Is
null
an acceptable element value? - Will the method ever return
null
?
All of these things are worth considering - and most of them were worth considering long before LINQ.
The moral is really, "Make sure you know how something behaves before you call it." That was true before LINQ, and LINQ hasn't changed it. It's just introduced two possibilities (deferred execution and streaming results) which were rarely present before.