Junior · Explain · Mutation review

How do a filtered copy and RemoveAll differ in ownership, aliasing and allocation despite returning the same kept values?

Think through your answer before opening the explanation.

Coding interviews

Reveal answer and reasoning

A request to remove matching items needs an ownership decision: return a filtered copy or mutate an exclusively owned list. This lesson reviews a common bug where code removes elements while a foreach enumerator is traversing the same list. The executable solution demonstrates two deliberate alternatives without relying on an exception message or accidental enumerator behavior. Returning a copy and mutating in place can both be correct, but they are not interchangeable for callers holding aliases.

State which object owns the change. The program creates a separate owned list for RemoveAll so it can demonstrate compaction without altering the original source that the first result was derived from.

Filtering and RemoveAll each take O(n) predicate work. The filtered array requires O(r) result storage, while RemoveAll compacts the owned list in place with constant auxiliary state. Constructing the separate demonstration copy itself costs O(n) storage; do not omit that cost when describing this exact program. Space analysis must include demonstration setup when discussing the complete executable, even if the library operation itself compacts in place.

A copy-returning API has required output storage; a mutating API may reduce retained capacity only under another explicit operation. Removing elements does not mean the backing array immediately shrinks to the kept count.

What a strong answer covers

  • A request to remove matching items needs an ownership decision: return a filtered copy or mutate an exclusively owned list.
  • ToArray forces the filtered query before the original list is displayed, fixing that result to the observed values.
  • Filtering and RemoveAll each take O(n) predicate work.

Common pitfall

A deferred Where query is not yet a snapshot, so source mutation before enumeration changes its result. Removing by increasing index can skip shifted elements. Concurrent mutation adds another ownership problem that neither a filtered query nor an unsynchronized list solves automatically.

Follow-up questions

  1. Test all-matching, none-matching and alternating lists. Hint: count the removed items separately from the kept items and verify the original list remains unchanged only for the copy-returning path.
  2. Does returning IReadOnlyList alone guarantee that the underlying list cannot change?

Self-review

Choose what to revisit. These marks are your own assessment and are separate from lesson completion.

Primary references

Open lesson and code ↗

← All interview questions