Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions CodeGen/Generators/UnitsNetGen/QuantityGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,21 +103,24 @@ namespace UnitsNet

private void GenerateInterfaceExtensions()
{
// generate the base interface (either IVectorQuantity, IAffineQuantity or ILogarithmicQuantity)
Writer.WL($@"
IQuantity<{_quantity.Name}, {_unitEnumName}>, ");

// generate ILogarithmicQuantity, IAffineQuantity or ILinearQuantity
if (_quantity.Logarithmic)
{
Writer.WL(@$"
ILogarithmicQuantity<{_quantity.Name}, {_unitEnumName}>,");
Writer.WL($@"
ILogarithmicQuantity<{_quantity.Name}>,");
}
else if (!string.IsNullOrEmpty(_quantity.AffineOffsetType))
{
Writer.WL(@$"
IAffineQuantity<{_quantity.Name}, {_unitEnumName}, {_quantity.AffineOffsetType}>,");
Writer.WL($@"
IAffineQuantity<{_quantity.Name}, {_quantity.AffineOffsetType}>,");
}
else // the default quantity type implements the IVectorQuantity interface
else // the default quantity type implements the ILinearQuantity interface
{
Writer.WL(@$"
IArithmeticQuantity<{_quantity.Name}, {_unitEnumName}>,");
Writer.WL($@"
ILinearQuantity<{_quantity.Name}>,");
}

Writer.WL(@"
Expand Down
12 changes: 6 additions & 6 deletions UnitsNet/Extensions/LogarithmicQuantityExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public static TQuantity Sum<TSource, TQuantity>(this IEnumerable<TSource> source
/// logarithmic space.
/// </remarks>
public static TQuantity Sum<TQuantity, TUnit>(this IEnumerable<TQuantity> quantities, TUnit targetUnit)
where TQuantity : ILogarithmicQuantity<TQuantity, TUnit>
where TQuantity : ILogarithmicQuantity<TQuantity>, IQuantity<TQuantity, TUnit>
where TUnit : struct, Enum
{
if (quantities is null)
Expand Down Expand Up @@ -228,7 +228,7 @@ public static TQuantity Sum<TQuantity, TUnit>(this IEnumerable<TQuantity> quanti
/// logarithmic space.
/// </remarks>
public static TQuantity Sum<TSource, TQuantity, TUnit>(this IEnumerable<TSource> source, Func<TSource, TQuantity> selector, TUnit targetUnit)
where TQuantity : ILogarithmicQuantity<TQuantity, TUnit>
where TQuantity : ILogarithmicQuantity<TQuantity>, IQuantity<TQuantity, TUnit>

@angularsen angularsen Jul 18, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest keeping the two-parameter quantity interfaces, if viable.

I think this is simpler for consumers: they can choose between the unit-agnostic and unit-specific interfaces, instead of repeating both constraints in their own APIs:

where TQuantity : ILogarithmicQuantity<TQuantity>, IQuantity<TQuantity, TUnit>

A composite interface captures that relationship directly:

public interface ILogarithmicQuantity<TSelf, TUnit> :
    IQuantity<TSelf, TUnit>,
    ILogarithmicQuantity<TSelf>
    where TSelf : ILogarithmicQuantity<TSelf, TUnit>
    where TUnit : struct, Enum
{
}

This matches the existing shape of the quantity interfaces (before the PR):

IArithmeticQuantity<TSelf, TUnit>
IAffineQuantity<TSelf, TUnit, TOffset>
ILogarithmicQuantity<TSelf, TUnit>

To me, this represents a useful concept: “a logarithmic quantity with a known unit enum”, while avoiding repeated multi-constraint combinations in public APIs.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, this goes for all the interfaces; affine, logarithmic, arithmetic.

Can we preserve the two-parameter composite interfaces to avoid consumers having to specify multiple generic constraints?

where TUnit : struct, Enum
{
return source.Select(selector).Sum(targetUnit);
Expand Down Expand Up @@ -316,7 +316,7 @@ public static TQuantity ArithmeticMean<TSource, TQuantity>(this IEnumerable<TSou
/// averaged, and then the result is converted back to logarithmic space using the same unit.
/// </remarks>
public static TQuantity ArithmeticMean<TQuantity, TUnit>(this IEnumerable<TQuantity> quantities, TUnit unit)
where TQuantity : ILogarithmicQuantity<TQuantity, TUnit>
where TQuantity : ILogarithmicQuantity<TQuantity>, IQuantity<TQuantity, TUnit>
where TUnit : struct, Enum
{
if (quantities is null)
Expand Down Expand Up @@ -371,7 +371,7 @@ public static TQuantity ArithmeticMean<TQuantity, TUnit>(this IEnumerable<TQuant
/// averaged, and then the result is converted back to logarithmic space using the same unit.
/// </remarks>
public static TQuantity ArithmeticMean<TSource, TQuantity, TUnit>(this IEnumerable<TSource> source, Func<TSource, TQuantity> selector, TUnit targetUnit)
where TQuantity : ILogarithmicQuantity<TQuantity, TUnit>
where TQuantity : ILogarithmicQuantity<TQuantity>, IQuantity<TQuantity, TUnit>
where TUnit : struct, Enum
{
return ArithmeticMean(source.Select(selector), targetUnit);
Expand Down Expand Up @@ -456,7 +456,7 @@ public static TQuantity GeometricMean<TSource, TQuantity>(this IEnumerable<TSour
/// logarithmic quantities is equal to the sum the values, converted in unit of the first element.
/// </remarks>
public static TQuantity GeometricMean<TQuantity, TUnit>(this IEnumerable<TQuantity> quantities, TUnit targetUnit)
where TQuantity : ILogarithmicQuantity<TQuantity, TUnit>
where TQuantity : ILogarithmicQuantity<TQuantity>, IQuantity<TQuantity, TUnit>
where TUnit : struct, Enum
{
if (quantities is null)
Expand Down Expand Up @@ -506,7 +506,7 @@ public static TQuantity GeometricMean<TQuantity, TUnit>(this IEnumerable<TQuanti
/// logarithmic quantities is equal to the sum the values, converted in unit of the first element.
/// </remarks>
public static TQuantity GeometricMean<TSource, TQuantity, TUnit>(this IEnumerable<TSource> source, Func<TSource, TQuantity> selector, TUnit targetUnit)
where TQuantity : ILogarithmicQuantity<TQuantity, TUnit>
where TQuantity : ILogarithmicQuantity<TQuantity>, IQuantity<TQuantity, TUnit>
where TUnit : struct, Enum
{
return source.Select(selector).GeometricMean(targetUnit);
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/Acceleration.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/AmountOfSubstance.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/AmplitudeRatio.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/Angle.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/Area.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/AreaDensity.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/AreaMomentOfInertia.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/BitRate.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/Compressibility.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/Density.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/DoseAreaProduct.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/Duration.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/DynamicViscosity.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/ElectricAdmittance.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/ElectricApparentPower.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/ElectricCapacitance.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/ElectricCharge.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/ElectricChargeDensity.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/ElectricConductance.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/ElectricConductivity.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/ElectricCurrent.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/ElectricField.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/ElectricImpedance.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion UnitsNet/GeneratedCode/Quantities/ElectricInductance.g.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading