Skip to content

Commit b3068cc

Browse files
🐛 Fix: Block inherited Add method on AppItemGroup (#305)
* Fix: shadow inherited Add method to prevent silent state corruption in AppItemGroup Shadows the inherited `Add` method with `new void Add(AppItem item)` that throws `NotSupportedException`. This ensures callers trying to directly `Add` to an `AppItemGroup` are immediately blocked, protecting the internal collection and filter state as validated by existing unit tests. * Fix: document why shadowed Add method coexists with InsertItem guard Adds explanatory documentation directly above the `public new void Add` method in `AppItemGroup` to clarify its purpose. The comment highlights that while `InsertItem` effectively prevents mutations via virtual dispatch, the shadowed `Add` method provides an immediate failure explicitly at the `AppItemGroup` API boundary to prevent developers from accidentally bypassing the tracking mechanism by calling the method directly on the class. * Update Models/AppItemGroup.cs --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: Mike Knight <173126+mikekthx@users.noreply.github.com>
1 parent 9739810 commit b3068cc

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

Models/AppItemGroup.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ public class AppItemGroup : BulkObservableCollection<AppItem>
4141
// Also true during base-class construction (field initializer runs before base ctor).
4242
private bool _suppressGuard = true;
4343

44+
// Shadows the non-virtual base Add to give callers an immediate, unambiguous
45+
// failure. InsertItem also throws as defense-in-depth, but that requires going
46+
// through the virtual dispatch chain; this makes the prohibition self-documenting
47+
// on the public API. Internal ReplaceAllGuarded uses Collection<T>.Add →
48+
// InsertItem (compile-time dispatch via BulkObservableCollection<T>) and never
49+
// reaches this shadow.
50+
public new void Add(AppItem item) =>
51+
throw new NotSupportedException(
52+
$"Direct Add/Insert bypasses _allItems and corrupts filter state. Use the {nameof(AppItemGroup)}-level APIs.");
53+
4454
// Wraps ReplaceAll with the mutation guard suppressed, so ApplyFilter and ApplyCollapseState
4555
// can batch-replace the visible collection without the guard interfering.
4656
private void ReplaceAllGuarded(IEnumerable<AppItem> items)

0 commit comments

Comments
 (0)