Skip to content

Add IValueQuantity<TValue> interface to expose the value type #1207

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Feb 26, 2023
19 changes: 9 additions & 10 deletions CodeGen/Generators/UnitsNetGen/QuantityGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,20 +263,10 @@ private void GenerateProperties()
/// The numeric value this quantity was constructed with.
/// </summary>
public {_valueType} Value => _value;
");

Writer.WL(@"
/// <inheritdoc />
QuantityValue IQuantity.Value => _value;
");
// Need to provide explicit interface implementation for decimal quantities like Information
if (_quantity.ValueType == "decimal")
Writer.WL(@"
/// <inheritdoc cref=""IDecimalQuantity.Value""/>
decimal IDecimalQuantity.Value => _value;
");

Writer.WL($@"
Enum IQuantity.Unit => Unit;

/// <inheritdoc />
Expand Down Expand Up @@ -959,6 +949,15 @@ double IQuantity.As(Enum unit)
return (double)As(typedUnit);
}}

/// <inheritdoc />
{_quantity.ValueType} IValueQuantity<{_quantity.ValueType}>.As(Enum unit)
{{
if (!(unit is {_unitEnumName} typedUnit))
throw new ArgumentException($""The given unit is of type {{unit.GetType()}}. Only {{typeof({_unitEnumName})}} is supported."", nameof(unit));

return As(typedUnit);
}}

/// <summary>
/// Converts this {_quantity.Name} to another {_quantity.Name} with the unit representation <paramref name=""unit"" />.
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions CodeGen/Generators/UnitsNetGen/UnitTestBaseClassGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ public void DefaultCtor_ReturnsQuantityWithZeroValueAndBaseUnit()
var quantity = new {_quantity.Name}();
Assert.Equal(0, quantity.Value);");
if (_quantity.ValueType == "decimal") Writer.WL(@"
Assert.Equal(0m, ((IDecimalQuantity)quantity).Value);");
Assert.Equal(0m, ((IValueQuantity<decimal>)quantity).Value);");
Writer.WL($@"
Assert.Equal({_baseUnitFullName}, quantity.Unit);
}}
Expand Down Expand Up @@ -278,7 +278,7 @@ public void As_SIUnitSystem_ThrowsArgumentExceptionIfNotSupported()

if (SupportsSIUnitSystem)
{{
var value = (double) AsWithSIUnitSystem();
var value = Convert.ToDouble(AsWithSIUnitSystem());
Assert.Equal(1, value);
}}
else
Expand Down
5 changes: 5 additions & 0 deletions Common/UnitDefinitions/Power.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
{
"SingularName": "Watt",
"PluralName": "Watts",
"BaseUnits": {
"L": "Meter",
"M": "Kilogram",
"T": "Second"
},
"FromUnitToBaseFunc": "{x}",
"FromBaseToUnitFunc": "{x}",
"Prefixes": [ "Femto", "Pico", "Nano", "Micro", "Milli", "Deci", "Deca", "Kilo", "Mega", "Giga", "Tera", "Peta" ],
Expand Down
4 changes: 2 additions & 2 deletions UnitsNet.Serialization.JsonNet/AbbreviatedUnitsConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public override void WriteJson(JsonWriter writer, IQuantity? quantity, JsonSeria

// write the 'Value' using the actual type
writer.WritePropertyName(ValueProperty);
if (quantity is IDecimalQuantity decimalQuantity)
if (quantity is IValueQuantity<decimal> decimalQuantity)
{
// cannot use `writer.WriteValue(decimalQuantity.Value)`: there is a hidden EnsureDecimalPlace(..) method call inside it that converts '123' to '123.0'
writer.WriteRawValue(decimalQuantity.Value.ToString(CultureInfo.InvariantCulture));
Expand Down Expand Up @@ -177,7 +177,7 @@ protected string GetQuantityType(IQuantity quantity)
{
value = default;
}
else if (quantityInfo.Zero is IDecimalQuantity)
else if (quantityInfo.Zero is IValueQuantity<decimal>)
{
value = decimal.Parse(valueToken, CultureInfo.InvariantCulture);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ protected ValueUnit ConvertIQuantity(IQuantity quantity)
{
quantity = quantity ?? throw new ArgumentNullException(nameof(quantity));

if (quantity is IDecimalQuantity d)
if (quantity is IValueQuantity<decimal> d)
{
return new ExtendedValueUnit
{
Expand Down
43 changes: 43 additions & 0 deletions UnitsNet.Tests/CustomCode/IQuantityTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,48 @@ public void ToUnit_GivenSIUnitSystem_ReturnsSIQuantity()
Assert.Equal(0.0508, inSI.Value);
Assert.Equal(LengthUnit.Meter, inSI.Unit);
}


[Fact]
public void IQuantityTUnitDouble_Value_ReturnsDouble()
{
IQuantity<TemperatureUnit, double> doubleQuantity = Temperature.FromDegreesCelsius(1234.5);
Assert.IsType<double>(doubleQuantity.Value);
}

[Fact]
public void IQuantityTUnitDouble_AsEnum_ReturnsDouble()
{
IQuantity<TemperatureUnit, double> doubleQuantity = Temperature.FromDegreesCelsius(1234.5);
Assert.IsType<double>(doubleQuantity.As(TemperatureUnit.Kelvin));
}

[Fact]
public void IQuantityTUnitDouble_AsUnitSystem_ReturnsDouble()
{
IQuantity<TemperatureUnit, double> doubleQuantity = Temperature.FromDegreesCelsius(1234.5);
Assert.IsType<double>(doubleQuantity.As(UnitSystem.SI));
}

[Fact]
public void IQuantityTUnitDecimal_Value_ReturnsDecimal()
{
IQuantity<InformationUnit, decimal> decimalQuantity = Information.FromKilobytes(1234.5);
Assert.IsType<decimal>(decimalQuantity.Value);
}

[Fact]
public void IQuantityTUnitDecimal_AsEnum_ReturnsDecimal()
{
IQuantity<InformationUnit, decimal> decimalQuantity = Information.FromKilobytes(1234.5);
Assert.IsType<decimal>(decimalQuantity.As(InformationUnit.Byte));
}

[Fact]
public void IQuantityTUnitDecimal_AsUnitSystem_ReturnsDecimal()
{
IQuantity<PowerUnit, decimal> decimalQuantity = Power.FromMegawatts(1234.5);
Assert.IsType<decimal>(decimalQuantity.As(UnitSystem.SI));
}
}
}
2 changes: 1 addition & 1 deletion UnitsNet.Tests/CustomCode/PowerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace UnitsNet.Tests
{
public class PowerTests : PowerTestsBase
{
protected override bool SupportsSIUnitSystem => false;
protected override bool SupportsSIUnitSystem => true;
protected override decimal FemtowattsInOneWatt => 1e15m;

protected override decimal GigajoulesPerHourInOneWatt => 3600e-9m;
Expand Down

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.

2 changes: 1 addition & 1 deletion UnitsNet.Tests/GeneratedCode/TestsBase/AngleTestsBase.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.

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.

2 changes: 1 addition & 1 deletion UnitsNet.Tests/GeneratedCode/TestsBase/AreaTestsBase.g.cs

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

4 changes: 2 additions & 2 deletions UnitsNet.Tests/GeneratedCode/TestsBase/BitRateTestsBase.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.

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.

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.

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.

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.

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.

Loading