Background
Many assertion types in TUnit.Assertions carry a dual generic parameter pair <TCollection, TItem> (e.g. CollectionAssertionBase<TCollection, TItem>, CollectionCountSource<TCollection, TItem>, ListAssertionBase<TList, TItem>). The TCollection parameter earns its keep where a drill-in genuinely needs the concrete shape (e.g. ItemAt requires IList<TItem>, dictionary key/value access requires the dictionary interface), and where And/Or continuations must preserve the shape-specific assertion surface.
However, some types/methods thread TCollection through purely as a pass-through and never use it beyond re-stating it in the return type. Each redundant generic parameter:
- adds an extra type argument the compiler must infer (or worse, the user must spell out),
- worsens overload-resolution behavior and error messages,
- multiplies the surface the covariant + pinned dual-overload strategy in
AssertionExtensionGenerator has to cover.
Task
- Audit all assertion/source/continuation types carrying both
TCollection (or TList/TDictionary) and TItem.
- Classify each: does any member actually require the concrete collection type (drill-in, shape-preserving And/Or), or is it pass-through only?
- For pass-through-only cases, collapse to
TItem-only (store the collection as IEnumerable<TItem> internally).
- Verify call-site inference improves (or at minimum does not regress) via the snapshot tests and the public API tests.
Notes
- This is a public-API-shape change in places; snapshot tests must be re-verified.
- Must not regress the shape-preserving And/Or narrowing where it is load-bearing (lists, dictionaries, sets).
Part of a generics-DX review of the assertions library; see also the related issues on overload-inference heuristics, a pre-work preservation analyzer, and C# 14 extension members.
Background
Many assertion types in
TUnit.Assertionscarry a dual generic parameter pair<TCollection, TItem>(e.g.CollectionAssertionBase<TCollection, TItem>,CollectionCountSource<TCollection, TItem>,ListAssertionBase<TList, TItem>). TheTCollectionparameter earns its keep where a drill-in genuinely needs the concrete shape (e.g.ItemAtrequiresIList<TItem>, dictionary key/value access requires the dictionary interface), and where And/Or continuations must preserve the shape-specific assertion surface.However, some types/methods thread
TCollectionthrough purely as a pass-through and never use it beyond re-stating it in the return type. Each redundant generic parameter:AssertionExtensionGeneratorhas to cover.Task
TCollection(orTList/TDictionary) andTItem.TItem-only (store the collection asIEnumerable<TItem>internally).Notes
Part of a generics-DX review of the assertions library; see also the related issues on overload-inference heuristics, a pre-work preservation analyzer, and C# 14 extension members.