Skip to content

Enumerate a collection that is passed as the root object - #86

Merged
tgharold merged 3 commits into
masterfrom
tgh-20261002-enumerate-root-collection
Oct 2, 2026
Merged

tgharold merged 3 commits into
masterfrom
tgh-20261002-enumerate-root-collection

Conversation

@tgharold

@tgharold tgharold commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Motivation

A collection passed to the validator as the root object was never enumerated. Run(new List<Item> { ... }) returned true even when an item was invalid, and a root array reported its items through SyncRoot, as SyncRoot[0].Name. A caller who validates a list directly got a silent pass.

The only job of the EnumerateItems flag was to keep the root from being enumerated. A collection that a property holds takes a queue step of its own, so no other object that the walk validates as an object was ever a collection that should skip enumeration. The flag was therefore dead weight, and removing it makes the rule simple: a collection that the walk validates as an object is also enumerated.

This is part 1 of 3 small PRs, in this order: root collection (this one), nested class-level error path, instance properties only. The other two stack on this branch.

Summary

  • A collection passed as the root object is validated as an object first, so its own attributes run. Then its items are validated. The error starts with the index of the item: [1].Name.
  • Remove the EnumerateItems flag from the work item and the enqueue methods. An array or ArrayList as the root now reports [0].Name and not SyncRoot[0].Name.
  • README and CHANGELOG: the changelog entry says that a model that passed before can fail now, and the changed member name is listed with the other BREAKING member-name changes. A lazy sequence passed in as the root now runs during validation.

Test plan

  • Full suite on net8.0 and net10.0: 579 passed, 7 skipped, 0 failed
  • net481 test project builds with 0 warnings and 0 errors (-p:IncludeNetFramework=true)
  • The new specs in OddShapeTests were written first and fail without the fix (commit order: specs, fix, docs)
  • CI on Windows runs the net481 tests

tgharold and others added 3 commits October 2, 2026 11:19
The validator never enumerated the root object, so a List passed in
directly hid its items and passed, and a root array reported its items
through SyncRoot. The specs expect the items at their index with no
name in front, such as "[0].Name".

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The EnumerateItems flag kept the root from being enumerated, and that
was its only effect: an object that a property holds is never a
collection here, because a property's collection takes a step of its
own in the queue. Remove the flag, so any collection that the walk
validates as an object is also enumerated.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@tgharold
tgharold merged commit 1d8d547 into master Oct 2, 2026
3 checks passed
@tgharold
tgharold deleted the tgh-20261002-enumerate-root-collection branch October 2, 2026 20:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant