You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add static abstract Info and obsolete QuantityInfo instance member on interfaces (#1675)
Per discussion on #1657, this introduces a static abstract `Info` member
on the IQuantityOfType<TQuantity> and IQuantity<TSelf,TUnitType>
interfaces under #if NET, marks the existing instance QuantityInfo
property as [Obsolete] on .NET 5+, and adds GetQuantityInfo() extension
methods on QuantityExtensions so callers have a single discoverable API
that works on every TFM.
Why
- The instance QuantityInfo property invariably returns a per-type
static value. Exposing it as an instance member implies it can vary per
instance, which it cannot, and incurs interface dispatch (boxing on
structs) for every call.
- The static abstract member lets generic algorithms reach the info with
`TSelf.Info` directly, no boxing, no virtual call.
- The extension method pair (`GetQuantityInfo()` /
`GetQuantityInfo<TUnit>()`) is the discoverable replacement for callers
that only have an `IQuantity` reference. It looks the quantity up via
`UnitsNetSetup.Default.Quantities`.
- Keeping the instance property obsolete (warning) instead of removing
it preserves source compatibility for existing callers and the
netstandard2.0 contract. We can promote to error / remove once
netstandard2.0 is dropped.
Implementation notes
- Generated quantities already expose `public static QuantityInfo<TSelf,
TUnitType> Info { get; }`, which directly satisfies the typed static
abstract. The non-generic `IQuantityOfType<TSelf>.Info` is satisfied by
a default static implementation in IQuantity<TSelf,TUnitType>: `static
QuantityInfo IQuantityOfType<TSelf>.Info => TSelf.Info;`. No codegen
change required.
- The IQuantity bridge `QuantityInfo IQuantity.QuantityInfo =>
QuantityInfo;` chain inside the interfaces uses #pragma to suppress the
obsolete warning on the bridge itself.
- Internal callers in UnitsNet were migrated to either `TSelf.Info` /
`TSelf.From` (where the generic constraint allows) or
`quantity.GetQuantityInfo()` (where it doesn't). Callers that must keep
working for custom quantities not registered in `UnitsNetSetup.Default`
(JsonNet serialization, debugger proxy, QuantityTypeConverter) keep
using the instance member with a `#pragma warning disable CS0618` and a
comment explaining why.
- HowMuch test custom quantity changed `public static readonly` field to
`public static QuantityInfo Info { get; }` property to satisfy the
static abstract.
- Tests added for round-trip equivalence between `Mass.Info`,
`mass.GetQuantityInfo()`, `TQuantity.Info` (via static abstract on
IQuantityOfType<T>), and `TSelf.Info` (via static abstract on
IQuantity<TSelf,TUnit>).
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments