Split from #221 (part c of three). Parent issue has the full sweep context.
The pattern
A constructor (or a method it directly calls) populates a collection field from the class's own factory, then subscribes to each element in a loop. The elements are owned by the class via its own collection — co-lifetimed, a collectable cycle, not a leak.
public ListsAndGridsViewModel() {
Items1 = CreateData(); // own factory fills the field
foreach (var model in Items1)
model.PropertyChanged += (s, a) => OnPropertyChanged(...); // <- flagged today
}
Evidence: MaterialDesignInXamlToolkit src/MainDemo.Wpf/Domain/ListsAndGridsViewModel.cs:16-17 (both demo-app variants).
Design guardrails (fixed at split time)
- The loop variable must be provably drawn from a field of
this (foreach (var x in FieldOrProperty) where the member is this-owned), and that member must be assigned in the same class from a constructor/factory call or collection initializer — not a ctor parameter, not an injected/service-located value. Injected collections keep today's warning (unknown element lifetime).
- Same-method scope for the loop; the field-population evidence may live in the same ctor or another member of the same class (class-level scan, same mechanism the field-based
-= search already uses).
- Negative control:
foreach over a collection parameter (or a field assigned from a ctor parameter) + += on elements → still flagged.
Acceptance
- Sample with the self-populated-collection shape (silent) + the injected-collection negative control (flagged), CI assertions both ways.
- Standard gates (
run_tests.py, ruff, mypy; extractor half via CI).
Refs: docs/notes/oracle-sweep-2026-07-10.md, docs/notes/field-notes-patterns.md entry 15.
Split from #221 (part c of three). Parent issue has the full sweep context.
The pattern
A constructor (or a method it directly calls) populates a collection field from the class's own factory, then subscribes to each element in a loop. The elements are owned by the class via its own collection — co-lifetimed, a collectable cycle, not a leak.
Evidence: MaterialDesignInXamlToolkit
src/MainDemo.Wpf/Domain/ListsAndGridsViewModel.cs:16-17(both demo-app variants).Design guardrails (fixed at split time)
this(foreach (var x in FieldOrProperty)where the member is this-owned), and that member must be assigned in the same class from a constructor/factory call or collection initializer — not a ctor parameter, not an injected/service-located value. Injected collections keep today's warning (unknown element lifetime).-=search already uses).foreachover a collection parameter (or a field assigned from a ctor parameter) ++=on elements → still flagged.Acceptance
run_tests.py,ruff,mypy; extractor half via CI).Refs:
docs/notes/oracle-sweep-2026-07-10.md,docs/notes/field-notes-patterns.mdentry 15.