From 54808cad06da07192f89123171ed659ac428d3f6 Mon Sep 17 00:00:00 2001 From: Andreas Gullberg Larsen Date: Thu, 23 Jul 2026 00:33:30 +0200 Subject: [PATCH] Support partial unit systems Extracted from angularsen/UnitsNet#1544 (https://github.com/angularsen/UnitsNet/pull/1544) because representing a unit system for only the dimensions an application uses is useful independently of QuantityValue. Moving it out gives the API change focused review and reduces the original PR's scope. Changes: - Allow UnitSystem to be constructed from any BaseUnits value defining at least one dimension. - Continue rejecting null and fully undefined base-unit sets. - Clarify the constructor documentation and exception message. Tests: - Change the seven previously rejected one-dimension-missing cases to assert successful construction. - Add a single-dimension UnitSystem case. - Add a dedicated assertion that BaseUnits.Undefined remains invalid. - Verify all UnitSystemTests on net10.0 and net48 (16 tests per target). --- UnitsNet.Tests/UnitSystemTests.cs | 13 +++++++++++-- UnitsNet/UnitSystem.cs | 4 ++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/UnitsNet.Tests/UnitSystemTests.cs b/UnitsNet.Tests/UnitSystemTests.cs index 4b21aac342..6dbc1c8977 100644 --- a/UnitsNet.Tests/UnitSystemTests.cs +++ b/UnitsNet.Tests/UnitSystemTests.cs @@ -34,11 +34,20 @@ public void ConstructorThrowsArgumentNullExceptionForNullBaseUnits() [InlineData(LengthUnit.Meter, MassUnit.Kilogram, DurationUnit.Second, ElectricCurrentUnit.Ampere, null, AmountOfSubstanceUnit.Mole, LuminousIntensityUnit.Candela)] [InlineData(LengthUnit.Meter, MassUnit.Kilogram, DurationUnit.Second, ElectricCurrentUnit.Ampere, TemperatureUnit.Kelvin, null, LuminousIntensityUnit.Candela)] [InlineData(LengthUnit.Meter, MassUnit.Kilogram, DurationUnit.Second, ElectricCurrentUnit.Ampere, TemperatureUnit.Kelvin, AmountOfSubstanceUnit.Mole, null)] - public void ConstructorThrowsArgumentExceptionWithUndefinedUnits(LengthUnit? length, MassUnit? mass, DurationUnit? time, ElectricCurrentUnit? current, + [InlineData(LengthUnit.Meter, null, null, null, null, null, null)] + public void ConstructorSupportsPartialDimensions(LengthUnit? length, MassUnit? mass, DurationUnit? time, ElectricCurrentUnit? current, TemperatureUnit? temperature, AmountOfSubstanceUnit? amount, LuminousIntensityUnit? luminousIntensity) { var baseUnits = new BaseUnits(length, mass, time, current, temperature, amount, luminousIntensity); - Assert.Throws(() => new UnitSystem(baseUnits)); + var unitSystem = new UnitSystem(baseUnits); + + Assert.Equal(baseUnits, unitSystem.BaseUnits); + } + + [Fact] + public void ConstructorThrowsArgumentExceptionWithUndefinedUnits() + { + Assert.Throws(() => new UnitSystem(BaseUnits.Undefined)); } [Fact] diff --git a/UnitsNet/UnitSystem.cs b/UnitsNet/UnitSystem.cs index 0f57cac20f..5ce264e434 100644 --- a/UnitsNet/UnitSystem.cs +++ b/UnitsNet/UnitSystem.cs @@ -16,11 +16,11 @@ public sealed class UnitSystem : IEquatable /// /// Creates an instance of a unit system with the specified base units. /// - /// The base units for the unit system. + /// One or more base units that define the unit system. public UnitSystem(BaseUnits baseUnits) { if (baseUnits is null) throw new ArgumentNullException(nameof(baseUnits)); - if (!baseUnits.IsFullyDefined) throw new ArgumentException("A unit system must have all base units defined.", nameof(baseUnits)); + if (baseUnits == BaseUnits.Undefined) throw new ArgumentException("A unit system must define at least one base unit.", nameof(baseUnits)); BaseUnits = baseUnits; }