Skip to content

Commit 8a9d731

Browse files
angularsenclaude
andcommitted
Revert IQuantity.UnitInfo DIM in favor of GetUnitInfo() extension on all TFMs
Reverts the default interface members added in #1649 and instead exposes GetUnitInfo() / GetUnitInfo<TUnit>() as extension methods on all target frameworks (previously gated behind #if !NET). Rationale (per @lipchev review feedback on #1649): - DIM bloats the IQuantity contract with members that just delegate to QuantityInfo[UnitKey]; aim is a leaner interface. - A custom IQuantity implementor overriding UnitInfo would silently diverge from internal lookups (UnitConverter, UnitAbbreviationsCache etc.) which always go through QuantityInfo, not the new property. - Calling the DIM through the IQuantity interface on a struct quantity causes interface dispatch and boxing per call. The extension method has none of these issues and gives the same ergonomic call-site (quantity.GetUnitInfo()) on every TFM. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 2a60bf9 commit 8a9d731

3 files changed

Lines changed: 8 additions & 34 deletions

File tree

UnitsNet.Tests/CustomCode/IQuantityTests.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,44 +60,44 @@ 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_TypedQuantity_ReturnsTypedUnitInfo()
8686
{
8787
IQuantity<LengthUnit> quantity = new Length(3.0, LengthUnit.Centimeter);
8888

89-
UnitInfo<LengthUnit> unitInfo = quantity.UnitInfo;
89+
UnitInfo<LengthUnit> unitInfo = quantity.GetUnitInfo();
9090

9191
Assert.Equal(LengthUnit.Centimeter, unitInfo.Value);
9292
Assert.Equal(nameof(LengthUnit.Centimeter), unitInfo.Name);
9393
}
9494

9595
[Fact]
96-
public void UnitInfo_MatchesUnit()
96+
public void GetUnitInfo_MatchesUnit()
9797
{
9898
Assert.All(Quantity.Infos.Select(x => x.Zero), quantity =>
9999
{
100-
Assert.Equal(quantity.Unit, quantity.UnitInfo.Value);
100+
Assert.Equal(quantity.Unit, quantity.GetUnitInfo().Value);
101101
});
102102
}
103103

UnitsNet/Extensions/QuantityExtensions.cs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,11 @@ 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>
1817
/// <param name="quantity">The quantity.</param>
1918
/// <returns>The <see cref="UnitInfo"/> for the quantity's unit.</returns>
20-
/// <remarks>
21-
/// On .NET 5+ targets, this is available as a default interface member property
22-
/// <c>IQuantity.UnitInfo</c> instead.
23-
/// </remarks>
2419
public static UnitInfo GetUnitInfo(this IQuantity quantity)
2520
{
2621
return quantity.QuantityInfo[quantity.UnitKey];
@@ -32,16 +27,11 @@ public static UnitInfo GetUnitInfo(this IQuantity quantity)
3227
/// <typeparam name="TUnit">The unit enum type.</typeparam>
3328
/// <param name="quantity">The quantity.</param>
3429
/// <returns>The <see cref="UnitInfo{TUnit}"/> for the quantity's unit.</returns>
35-
/// <remarks>
36-
/// On .NET 5+ targets, this is available as a default interface member property
37-
/// <c>IQuantity&lt;TUnitType&gt;.UnitInfo</c> instead.
38-
/// </remarks>
3930
public static UnitInfo<TUnit> GetUnitInfo<TUnit>(this IQuantity<TUnit> quantity)
4031
where TUnit : struct, Enum
4132
{
4233
return quantity.QuantityInfo[quantity.Unit];
4334
}
44-
#endif
4535

4636
/// <inheritdoc cref="IQuantity.As(UnitKey)" />
4737
/// <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)