Skip to content

Commit 7e06c06

Browse files
committed
Merge branch 'master' into add-gramforce
2 parents 72b52fb + 60a875a commit 7e06c06

6 files changed

Lines changed: 64 additions & 45 deletions

File tree

CodeGen/CodeGen.csproj

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,18 @@
55
<TargetFramework>net10.0</TargetFramework>
66
<LangVersion>latest</LangVersion>
77
<Nullable>enable</Nullable>
8-
<!-- Allow compile with various nullability warnings until fixed. -->
9-
<WarningsNotAsErrors>8600,8601,8603,8604,8618,8619,8625</WarningsNotAsErrors>
8+
<!--
9+
Inherits Directory.Build.props codes and adds nullability warnings the codegen sources
10+
have not been annotated for. All stay visible as warnings.
11+
CS8600 - null literal to non-nullable
12+
CS8601 - possible null reference assignment
13+
CS8603 - possible null reference return
14+
CS8604 - possible null reference argument
15+
CS8618 - non-nullable field uninitialized in ctor
16+
CS8619 - nullability mismatch
17+
CS8625 - null literal to non-nullable reference
18+
-->
19+
<WarningsNotAsErrors>$(WarningsNotAsErrors);8600;8601;8603;8604;8618;8619;8625</WarningsNotAsErrors>
1020
</PropertyGroup>
1121

1222
<ItemGroup>

Directory.Build.props

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,14 @@
1717
<PropertyGroup>
1818
<!-- Warning instead of compile error on obsolete errors.-->
1919
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
20-
<!-- 612: obsolete, 618: obsolete with message -->
21-
<WarningsNotAsErrors>612,618</WarningsNotAsErrors>
20+
<!--
21+
Warnings stay visible but do not fail the build. NU1903 (high) and NU1904 (critical) still fail.
22+
CS0612 - obsolete member
23+
CS0618 - obsolete member with message
24+
NU1901 - NuGet audit: low severity vulnerability
25+
NU1902 - NuGet audit: moderate severity vulnerability
26+
-->
27+
<WarningsNotAsErrors>612;618;NU1901;NU1902</WarningsNotAsErrors>
2228
</PropertyGroup>
2329

2430
<!-- Build symbol package (.snupkg) to distribute the PDB file for debugging, in addition to Source Link per recommendation: https://learn.microsoft.com/en-us/dotnet/standard/library-guidance/sourcelink -->

Directory.Packages.props

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
<ItemGroup>
66
<PackageVersion Include="System.Runtime.CompilerServices.Unsafe" Version="6.1.2" />
77
<PackageVersion Include="BenchmarkDotNet" Version="0.15.8" />
8-
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
8+
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.5.1" />
99
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
10-
<PackageVersion Include="NuGet.Protocol" Version="7.0.1" />
11-
<PackageVersion Include="Serilog" Version="4.3.0" />
10+
<PackageVersion Include="NuGet.Protocol" Version="7.3.1" />
11+
<PackageVersion Include="Serilog" Version="4.3.1" />
1212
<PackageVersion Include="Serilog.Sinks.Console" Version="6.1.1" />
1313
<PackageVersion Include="System.CommandLine.DragonFruit" Version="0.4.0-alpha.22272.1" />
1414
<PackageVersion Include="xunit" Version="2.9.3" />

UnitsNet.Tests/CustomCode/IQuantityTests.cs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,44 +60,59 @@ public void ToUnit_UnitSystem_ThrowsArgumentNullExceptionIfNull()
6060
}
6161

6262
[Fact]
63-
public void UnitInfo_ReturnsUnitInfoForQuantityUnit()
63+
public void GetUnitInfo_ReturnsUnitInfoForQuantityUnit()
6464
{
6565
var length = new Length(3.0, LengthUnit.Centimeter);
6666
IQuantity quantity = length;
6767

68-
UnitInfo unitInfo = quantity.UnitInfo;
68+
UnitInfo unitInfo = quantity.GetUnitInfo();
6969

7070
Assert.Equal(nameof(LengthUnit.Centimeter), unitInfo.Name);
7171
Assert.Equal(quantity.UnitKey, unitInfo.UnitKey);
7272
}
7373

7474
[Fact]
75-
public void UnitInfo_Zero_ReturnsBaseUnitInfo()
75+
public void GetUnitInfo_Zero_ReturnsBaseUnitInfo()
7676
{
7777
IQuantity quantity = Length.Info.Zero;
7878

79-
UnitInfo unitInfo = quantity.UnitInfo;
79+
UnitInfo unitInfo = quantity.GetUnitInfo();
8080

8181
Assert.Equal(Length.Info.BaseUnitInfo.UnitKey, unitInfo.UnitKey);
8282
}
8383

8484
[Fact]
85-
public void UnitInfo_TypedQuantity_ReturnsTypedUnitInfo()
85+
public void GetUnitInfo_ConcreteQuantity_ReturnsFullyTypedUnitInfo()
8686
{
87-
IQuantity<LengthUnit> quantity = new Length(3.0, LengthUnit.Centimeter);
87+
var quantity = new Length(3.0, LengthUnit.Centimeter);
8888

89-
UnitInfo<LengthUnit> unitInfo = quantity.UnitInfo;
89+
// Overload resolution picks GetUnitInfo<TQuantity, TUnit> for the concrete struct receiver,
90+
// returning the most specific UnitInfo<Length, LengthUnit>.
91+
UnitInfo<Length, LengthUnit> unitInfo = quantity.GetUnitInfo();
9092

9193
Assert.Equal(LengthUnit.Centimeter, unitInfo.Value);
9294
Assert.Equal(nameof(LengthUnit.Centimeter), unitInfo.Name);
9395
}
9496

9597
[Fact]
96-
public void UnitInfo_MatchesUnit()
98+
public void GetUnitInfo_TypedQuantityReference_FallsBackToNonGeneric()
99+
{
100+
IQuantity<LengthUnit> quantity = new Length(3.0, LengthUnit.Centimeter);
101+
102+
// The IQuantity<TUnit> reference does not satisfy the IQuantity<TSelf, TUnit> constraint
103+
// (TSelf would be IQuantity<MassUnit>), so resolution falls back to GetUnitInfo(IQuantity).
104+
UnitInfo unitInfo = quantity.GetUnitInfo();
105+
106+
Assert.Equal(LengthUnit.Centimeter, ((UnitInfo<LengthUnit>)unitInfo).Value);
107+
Assert.Equal(nameof(LengthUnit.Centimeter), unitInfo.Name);
108+
}
109+
110+
[Fact]
111+
public void GetUnitInfo_MatchesUnit()
97112
{
98113
Assert.All(Quantity.Infos.Select(x => x.Zero), quantity =>
99114
{
100-
Assert.Equal(quantity.Unit, quantity.UnitInfo.Value);
115+
Assert.Equal(quantity.Unit, quantity.GetUnitInfo().Value);
101116
});
102117
}
103118

UnitsNet/Extensions/QuantityExtensions.cs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,37 +11,41 @@ namespace UnitsNet;
1111
/// </summary>
1212
public static class QuantityExtensions
1313
{
14-
#if !NET
1514
/// <summary>
1615
/// Gets the <see cref="UnitInfo"/> for the unit this quantity was constructed with.
1716
/// </summary>
18-
/// <param name="quantity">The quantity.</param>
19-
/// <returns>The <see cref="UnitInfo"/> for the quantity's unit.</returns>
2017
/// <remarks>
21-
/// On .NET 5+ targets, this is available as a default interface member property
22-
/// <c>IQuantity.UnitInfo</c> instead.
18+
/// Picked by overload resolution for callers that only have an <see cref="IQuantity"/> reference.
19+
/// Concretely-typed callers (e.g. a <c>Mass</c> receiver) bind to the
20+
/// <see cref="GetUnitInfo{TQuantity,TUnit}(IQuantity{TQuantity,TUnit})"/> overload and get the
21+
/// more specific <see cref="UnitInfo{TQuantity,TUnit}"/> return.
2322
/// </remarks>
23+
/// <param name="quantity">The quantity.</param>
24+
/// <returns>The <see cref="UnitInfo"/> for the quantity's unit.</returns>
2425
public static UnitInfo GetUnitInfo(this IQuantity quantity)
2526
{
2627
return quantity.QuantityInfo[quantity.UnitKey];
2728
}
2829

2930
/// <summary>
30-
/// Gets the <see cref="UnitInfo{TUnit}"/> for the unit this quantity was constructed with.
31+
/// Gets the <see cref="UnitInfo{TQuantity,TUnit}"/> for the unit this quantity was constructed with.
3132
/// </summary>
32-
/// <typeparam name="TUnit">The unit enum type.</typeparam>
33-
/// <param name="quantity">The quantity.</param>
34-
/// <returns>The <see cref="UnitInfo{TUnit}"/> for the quantity's unit.</returns>
3533
/// <remarks>
36-
/// On .NET 5+ targets, this is available as a default interface member property
37-
/// <c>IQuantity&lt;TUnitType&gt;.UnitInfo</c> instead.
34+
/// Picked by overload resolution for concretely-typed receivers (e.g. <c>Mass</c>) where C# can
35+
/// infer both <typeparamref name="TQuantity"/> and <typeparamref name="TUnit"/> from the receiver's
36+
/// <see cref="IQuantity{TSelf,TUnit}"/> implementation. Callers with only an <see cref="IQuantity"/>
37+
/// reference fall back to the non-generic <see cref="GetUnitInfo(IQuantity)"/> overload.
3838
/// </remarks>
39-
public static UnitInfo<TUnit> GetUnitInfo<TUnit>(this IQuantity<TUnit> quantity)
39+
/// <typeparam name="TQuantity">The quantity type.</typeparam>
40+
/// <typeparam name="TUnit">The unit enum type.</typeparam>
41+
/// <param name="quantity">The quantity.</param>
42+
/// <returns>The <see cref="UnitInfo{TQuantity,TUnit}"/> for the quantity's unit.</returns>
43+
public static UnitInfo<TQuantity, TUnit> GetUnitInfo<TQuantity, TUnit>(this IQuantity<TQuantity, TUnit> quantity)
44+
where TQuantity : IQuantity<TQuantity, TUnit>
4045
where TUnit : struct, Enum
4146
{
4247
return quantity.QuantityInfo[quantity.Unit];
4348
}
44-
#endif
4549

4650
/// <inheritdoc cref="IQuantity.As(UnitKey)" />
4751
/// <remarks>This should be using UnitConverter.Default.ConvertValue(quantity, toUnit) </remarks>

UnitsNet/IQuantity.cs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,6 @@ public interface IQuantity : IFormattable
5858
/// as it avoids the boxing that would normally occur when casting the enum to <see cref="Enum" />.
5959
/// </remarks>
6060
UnitKey UnitKey { get; }
61-
62-
#if NET
63-
/// <summary>
64-
/// Gets the <see cref="UnitsNet.UnitInfo"/> for the unit this quantity was constructed with.
65-
/// </summary>
66-
/// <remarks>
67-
/// On targets that do not support default interface members (e.g. netstandard2.0),
68-
/// use the <c>GetUnitInfo()</c> extension method from <see cref="QuantityExtensions"/> instead.
69-
/// </remarks>
70-
UnitInfo UnitInfo => QuantityInfo[UnitKey];
71-
#endif
7261
}
7362

7463
/// <summary>
@@ -105,13 +94,8 @@ public interface IQuantity<TUnitType> : IQuantity
10594

10695
#if NET
10796

108-
/// <inheritdoc cref="IQuantity.UnitInfo"/>
109-
new UnitInfo<TUnitType> UnitInfo => QuantityInfo[Unit];
110-
11197
#region Implementation of IQuantity
11298

113-
UnitInfo IQuantity.UnitInfo => UnitInfo;
114-
11599
QuantityInfo IQuantity.QuantityInfo
116100
{
117101
get => QuantityInfo;

0 commit comments

Comments
 (0)