Skip to content

Commit 7e449a8

Browse files
authored
Generic math for UnitsNet in .NET 7 (#1164)
Co-authored-by: Andreas Gullberg Larsen <andreas.larsen84@gmail.com> Changes: - build UnitsNet in .NET 7 as well with very limited conditional compilation for the generic math interfaces - extended IQuantity interface hierarchy to support generic math (as the TSelf parameter for CRT pattern, and the underlying value type are needed) - automatically generated operator overloads and parsing methods are covered by the respective generic math interfaces Still to do: - also cover the manually added operator overloads in the *.extra.cs files with generic math interfaces - also implement ISpanParsable, which will need some work, especially in the QuantityParser - maybe for symmetry reasons also overload the unary + operator and implement IUnaryPlusOperators. However, I'm unsure because it's a pretty useless operator - resolve nullable reference types chaos: since multi-targeting with net7.0 even when disabling the nullability in the csproj I kept getting tons of errors for both netstandard2.0 and net7.0 builds, so for now I've disabled the respective warnings. We should fully use the nullable reference types feature in the whole code base also for .netstandard2.0 to solve this tangle Pain points: - multiplication with one operand of Quantity type and one operand of double/decimal type only supported with Quantity being the first parameter (when adding the commutative case, I get errors ![grafik](https://user-images.githubusercontent.com/30859615/206543723-613058a3-d3ea-4232-ae42-e37fe812ab5f.png) - I suspect we'll run into the same issues with some custom overloads involving commutative multiplication with different quantity types
1 parent 0502f38 commit 7e449a8

File tree

124 files changed

+807
-236
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

124 files changed

+807
-236
lines changed

CodeGen/Generators/UnitsNetGen/QuantityGenerator.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ namespace UnitsNet
6464
Writer.WLIfText(1, GetObsoleteAttributeOrNull(_quantity));
6565
Writer.W(@$"
6666
[DataContract]
67-
public readonly partial struct {_quantity.Name} : IQuantity<{_unitEnumName}>, ");
67+
public readonly partial struct {_quantity.Name} : {(_quantity.GenerateArithmetic ? "IArithmeticQuantity" : "IQuantity")}<{_quantity.Name}, {_unitEnumName}, {_quantity.ValueType}>, ");
6868
if (_quantity.ValueType == "decimal")
6969
{
7070
Writer.W("IDecimalQuantity, ");
@@ -239,9 +239,19 @@ private void GenerateStaticProperties()
239239
/// Gets an instance of this quantity with a value of 0 in the base unit {_quantity.BaseUnit}.
240240
/// </summary>
241241
public static {_quantity.Name} Zero {{ get; }}
242+
");
242243

243-
#endregion
244+
if (_quantity.GenerateArithmetic)
245+
{
246+
Writer.WL($@"
247+
/// <inheritdoc cref=""Zero""/>
248+
public static {_quantity.Name} AdditiveIdentity => Zero;
244249
");
250+
}
251+
252+
Writer.WL($@"
253+
#endregion
254+
");
245255
}
246256

247257
private void GenerateProperties()
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Licensed under MIT No Attribution, see LICENSE file at the root.
2+
// Copyright 2013 Andreas Gullberg Larsen (andreas.larsen84@gmail.com). Maintained at https://github.com/angularsen/UnitsNet.
3+
4+
#if NET7_0_OR_GREATER
5+
using UnitsNet.GenericMath;
6+
using Xunit;
7+
8+
namespace UnitsNet.Tests;
9+
10+
public class GenericMathExtensionsTests
11+
{
12+
[Fact]
13+
public void CanCalcSum()
14+
{
15+
Length[] values = { Length.FromCentimeters(100), Length.FromCentimeters(200) };
16+
17+
Assert.Equal(Length.FromCentimeters(300), values.Sum());
18+
}
19+
20+
[Fact]
21+
public void CanCalcAverage_ForQuantitiesWithDoubleValueType()
22+
{
23+
Length[] values = { Length.FromCentimeters(100), Length.FromCentimeters(200) };
24+
25+
Assert.Equal(Length.FromCentimeters(150), values.Average());
26+
}
27+
28+
[Fact]
29+
public void CanCalcAverage_ForQuantitiesWithDecimalValueType()
30+
{
31+
Information[] values = { Information.FromBytes(100), Information.FromBytes(200) };
32+
33+
Assert.Equal(Information.FromBytes(150), values.Average());
34+
}
35+
}
36+
37+
#endif

UnitsNet.Tests/UnitsNet.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>net6.0;net48</TargetFrameworks>
4+
<TargetFrameworks>net7.0;net48</TargetFrameworks>
55
<LangVersion>latest</LangVersion>
66
<IsTestProject>true</IsTestProject>
77
<NoWarn>CS0618</NoWarn>

UnitsNet/GeneratedCode/Quantities/Acceleration.g.cs

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/AmountOfSubstance.g.cs

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/AmplitudeRatio.g.cs

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/Angle.g.cs

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/ApparentEnergy.g.cs

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/ApparentPower.g.cs

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/Area.g.cs

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/AreaDensity.g.cs

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/AreaMomentOfInertia.g.cs

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/BitRate.g.cs

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/BrakeSpecificFuelConsumption.g.cs

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/Capacitance.g.cs

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/CoefficientOfThermalExpansion.g.cs

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnitsNet/GeneratedCode/Quantities/Compressibility.g.cs

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)