From c3259a4744ed82abf9d50cbdb16f5c13ec610bbd Mon Sep 17 00:00:00 2001 From: Andreas Gullberg Larsen Date: Sat, 1 Aug 2026 21:59:29 +0200 Subject: [PATCH] Document custom unit conversion overrides --- Docs/precision.md | 18 ++++++++++++++- UnitsNet.Tests/UnitConverterTest.cs | 36 +++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/Docs/precision.md b/Docs/precision.md index bf7b084858..668b19cccf 100644 --- a/Docs/precision.md +++ b/Docs/precision.md @@ -11,7 +11,23 @@ Units.NET was not designed for high-precision, but rather a tool of convenience - Centimeter => Meter => Kilometer - As a result, most conversions have a rounding error. The error is larger for units that are way larger or way smaller than the base unit. - A rounding error of `1e-5` is accepted for round-trip conversion of most units in the library. In many use cases this is sufficient, but for others this may not be acceptable. - - There is support for [custom conversion functions](https://github.com/angularsen/UnitsNet#convert-between-units-of-custom-quantity) between unit A to unit B, typically to add 3rd party units. This can also be used to improve the precision for specific conversions since it no longer converts via the base unit. + - In v6, unit conversion definitions can be customized before the converter is built. This can be used to override a built-in conversion factor or add conversion functions for custom quantities. + +## Overriding built-in unit conversions + +Built-in unit definitions can be customized through `UnitsNetSetup.ConfigureDefaults()` before the default setup is used: + +```csharp +UnitsNetSetup.ConfigureDefaults(builder => builder.ConfigureQuantity(() => + Pressure.PressureInfo.CreateDefault(units => + units.Configure(PressureUnit.InchOfWaterColumn, unit => + unit.WithConversionFactorFromBase(999))))); + +var pressure = Pressure.FromPascals(1); +double value = pressure.As(PressureUnit.InchOfWaterColumn); // 999 +``` + +For isolated conversions, create a custom `QuantityInfo` and pass it to a custom `UnitConverter` instead of changing the global defaults. See `Samples/UnitsNetSetup.Configuration/ConfigureWithCustomConversions.cs` for a complete example. ## Test precision diff --git a/UnitsNet.Tests/UnitConverterTest.cs b/UnitsNet.Tests/UnitConverterTest.cs index 60dfd7b2cb..6947f59e42 100644 --- a/UnitsNet.Tests/UnitConverterTest.cs +++ b/UnitsNet.Tests/UnitConverterTest.cs @@ -252,6 +252,42 @@ public void TryGetConversionFunction_WithCustomUnitConversion_ReturnsTrue(bool f Assert.Equal(1800, conversionFunction!(18)); }); } + + [Theory] + [MemberData(nameof(ConverterTestOptions))] + public void ConvertValue_WithCustomBuiltInUnitDefinition_UsesConfiguredConversion(bool freeze, ConversionCachingMode cachingMode, bool reduceConstants) + { + var customPressureInfo = Pressure.PressureInfo.CreateDefault(unitDefinitions => + unitDefinitions.Configure(PressureUnit.InchOfWaterColumn, definition => definition.WithConversionFactorFromBase(999))); + + var unitParser = new UnitParser([customPressureInfo]); + var convertOptions = new QuantityConverterBuildOptions(freeze, cachingMode, reduceConstants); + var unitConverter = UnitConverter.Create(unitParser, convertOptions); + + var pressure = Pressure.FromPascals(1); + + Assert.Multiple(() => + { + QuantityValue convertedValue = unitConverter.ConvertValue(1, PressureUnit.Pascal, PressureUnit.InchOfWaterColumn); + + Assert.Equal(999, convertedValue); + }, () => + { + QuantityValue convertedValue = unitConverter.ConvertValue(999, PressureUnit.InchOfWaterColumn, PressureUnit.Pascal); + + Assert.Equal(1, convertedValue); + }, () => + { + QuantityValue convertedValue = pressure.As(PressureUnit.InchOfWaterColumn, unitConverter); + + Assert.Equal(999, convertedValue); + }, () => + { + var convertedQuantity = pressure.ToUnit(PressureUnit.InchOfWaterColumn, unitConverter); + + Assert.Equal(999, convertedQuantity.Value); + }); + } [Theory]