@@ -25,7 +25,7 @@ public QuantityGenerator(Quantity quantity)
25
25
throw new ArgumentException ( $ "No unit found with SingularName equal to BaseUnit [{ _quantity . BaseUnit } ]. This unit must be defined.",
26
26
nameof ( quantity ) ) ;
27
27
28
- _valueType = quantity . ValueType ;
28
+ _valueType = "QuantityValue" ; // quantity.ValueType;
29
29
_unitEnumName = $ "{ quantity . Name } Unit";
30
30
31
31
BaseDimensions baseDimensions = quantity . BaseDimensions ;
@@ -77,14 +77,14 @@ public partial struct {_quantity.Name} : IQuantity<{_unitEnumName}>, ");
77
77
Writer . W ( "IDecimalQuantity, " ) ;
78
78
}
79
79
80
- Writer . WL ( $ "IComparable, IComparable<{ _quantity . Name } >, IConvertible, IFormattable") ;
80
+ Writer . WL ( $ "IEquatable< { _quantity . Name } >, IComparable, IComparable<{ _quantity . Name } >, IConvertible, IFormattable") ;
81
81
Writer . WL ( $@ "
82
82
{{
83
83
/// <summary>
84
84
/// The numeric value this quantity was constructed with.
85
85
/// </summary>
86
86
[DataMember(Name = ""Value"", Order = 0)]
87
- private readonly { _quantity . ValueType } _value;
87
+ private readonly { _valueType } _value;
88
88
89
89
/// <summary>
90
90
/// The unit this quantity was constructed with.
@@ -176,9 +176,9 @@ private void GenerateInstanceConstructors()
176
176
/// <param name=""value"">The numeric value to construct this quantity with.</param>
177
177
/// <param name=""unit"">The unit representation to construct this quantity with.</param>
178
178
/// <exception cref=""ArgumentException"">If value is NaN or Infinity.</exception>
179
- public { _quantity . Name } ({ _quantity . ValueType } value, { _unitEnumName } unit)
179
+ public { _quantity . Name } ({ _valueType } value, { _unitEnumName } unit)
180
180
{{" ) ;
181
- Writer . WL ( _quantity . ValueType == "double"
181
+ Writer . WL ( _valueType == "double"
182
182
? @"
183
183
_value = Guard.EnsureValidNumber(value, nameof(value));"
184
184
: @"
@@ -203,7 +203,7 @@ private void GenerateInstanceConstructors()
203
203
var firstUnitInfo = unitInfos.FirstOrDefault();
204
204
" ) ;
205
205
206
- Writer . WL ( _quantity . ValueType == "double"
206
+ Writer . WL ( _valueType == "double"
207
207
? @"
208
208
_value = Guard.EnsureValidNumber(value, nameof(value));"
209
209
: @"
@@ -262,15 +262,15 @@ private void GenerateProperties()
262
262
public { _valueType } Value => _value;
263
263
" ) ;
264
264
265
- // Need to provide explicit interface implementation for decimal quantities like Information
266
- if ( _quantity . ValueType != "double" )
267
- Writer . WL ( @"
268
- double IQuantity.Value => (double) _value;
265
+ Writer . WL ( $@ "
266
+ /// <inheritdoc />
267
+ { _valueType } IQuantity.Value => _value;
269
268
" ) ;
269
+ // Need to provide explicit interface implementation for decimal quantities like Information
270
270
if ( _quantity . ValueType == "decimal" )
271
271
Writer . WL ( @"
272
272
/// <inheritdoc cref=""IDecimalQuantity.Value""/>
273
- decimal IDecimalQuantity.Value => _value;
273
+ decimal IDecimalQuantity.Value => (decimal) _value;
274
274
" ) ;
275
275
276
276
Writer . WL ( $@ "
@@ -306,11 +306,11 @@ private void GenerateConversionProperties()
306
306
307
307
Writer . WL ( $@ "
308
308
/// <summary>
309
- /// Gets a <see cref=""double""/> value of this quantity converted into <see cref=""{ _unitEnumName } .{ unit . SingularName } ""/>
309
+ /// Gets the numeric value of this quantity converted into <see cref=""{ _unitEnumName } .{ unit . SingularName } ""/>
310
310
/// </summary>" ) ;
311
311
Writer . WLIfText ( 2 , GetObsoleteAttributeOrNull ( unit ) ) ;
312
312
Writer . WL ( $@ "
313
- public double { unit . PluralName } => As({ _unitEnumName } .{ unit . SingularName } );
313
+ public { _valueType } { unit . PluralName } => As({ _unitEnumName } .{ unit . SingularName } );
314
314
" ) ;
315
315
}
316
316
@@ -426,7 +426,7 @@ private void GenerateStaticFactoryMethods()
426
426
/// <exception cref=""ArgumentException"">If value is NaN or Infinity.</exception>" ) ;
427
427
Writer. WLIfText ( 2 , GetObsoleteAttributeOrNull ( unit ) ) ;
428
428
Writer. WL ( $@ "
429
- public static { _quantity . Name } From{ unit . PluralName } (QuantityValue { valueParamName } )
429
+ public static { _quantity . Name } From{ unit . PluralName } ({ _valueType } { valueParamName } )
430
430
{{
431
431
{ _valueType } value = ({ _valueType } ) { valueParamName } ;
432
432
return new { _quantity . Name } (value, { _unitEnumName } .{ unit . SingularName } );
@@ -651,7 +651,7 @@ private void GenerateArithmeticOperators()
651
651
}}
652
652
653
653
/// <summary>Get ratio value from dividing <see cref=""{ _quantity . Name } ""/> by <see cref=""{ _quantity . Name } ""/>.</summary>
654
- public static double operator /({ _quantity . Name } left, { _quantity . Name } right)
654
+ public static { _valueType } operator /({ _quantity . Name } left, { _quantity . Name } right)
655
655
{{
656
656
return left.{ _baseUnit . PluralName } / right.{ _baseUnit . PluralName } ;
657
657
}}
@@ -679,15 +679,15 @@ private void GenerateLogarithmicArithmeticOperators()
679
679
{{
680
680
// Logarithmic addition
681
681
// Formula: { x } * log10(10^(x/{ x } ) + 10^(y/{ x } ))
682
- return new { _quantity . Name } ({ x } * Math.Log10(Math.Pow(10, left.Value/{ x } ) + Math.Pow(10, right.GetValueAs(left.Unit)/{ x } )), left.Unit);
682
+ return new { _quantity . Name } ({ x } * Math.Log10(Math.Pow(10, (double) left.Value/{ x } ) + Math.Pow(10, (double) right.GetValueAs(left.Unit)/{ x } )), left.Unit);
683
683
}}
684
684
685
685
/// <summary>Get <see cref=""{ _quantity . Name } ""/> from logarithmic subtraction of two <see cref=""{ _quantity . Name } ""/>.</summary>
686
686
public static { _quantity . Name } operator -({ _quantity . Name } left, { _quantity . Name } right)
687
687
{{
688
688
// Logarithmic subtraction
689
689
// Formula: { x } * log10(10^(x/{ x } ) - 10^(y/{ x } ))
690
- return new { _quantity . Name } ({ x } * Math.Log10(Math.Pow(10, left.Value/{ x } ) - Math.Pow(10, right.GetValueAs(left.Unit)/{ x } )), left.Unit);
690
+ return new { _quantity . Name } ({ x } * Math.Log10(Math.Pow(10, (double) left.Value/{ x } ) - Math.Pow(10, (double) right.GetValueAs(left.Unit)/{ x } )), left.Unit);
691
691
}}
692
692
693
693
/// <summary>Get <see cref=""{ _quantity . Name } ""/> from logarithmic multiplication of value and <see cref=""{ _quantity . Name } ""/>.</summary>
@@ -751,6 +751,19 @@ private void GenerateEqualityAndComparison()
751
751
return left.Value > right.GetValueAs(left.Unit);
752
752
}}
753
753
754
+ /// <summary>Returns true if exactly equal.</summary>
755
+ /// <remarks>Consider using <see cref=""Equals({ _quantity . Name } , { _valueType } , ComparisonType)""/> for safely comparing floating point values.</remarks>
756
+ public static bool operator ==({ _quantity . Name } left, { _quantity . Name } right)
757
+ {{
758
+ return left.Equals(right);
759
+ }}
760
+ /// <summary>Returns true if not exactly equal.</summary>
761
+ /// <remarks>Consider using <see cref=""Equals({ _quantity . Name } , { _valueType } , ComparisonType)""/> for safely comparing floating point values.</remarks>
762
+ public static bool operator !=({ _quantity . Name } left, { _quantity . Name } right)
763
+ {{
764
+ return !(left == right);
765
+ }}
766
+
754
767
/// <inheritdoc />
755
768
public int CompareTo(object obj)
756
769
{{
@@ -763,7 +776,29 @@ public int CompareTo(object obj)
763
776
/// <inheritdoc />
764
777
public int CompareTo({ _quantity . Name } other)
765
778
{{
766
- return _value.CompareTo(other.GetValueAs(this.Unit));
779
+ var asFirstUnit = other.GetValueAs(this.Unit);
780
+ var asSecondUnit = GetValueAs(other.Unit);
781
+ return (_value.CompareTo(asFirstUnit) - other.Value.CompareTo(asSecondUnit)) / 2;
782
+ }}
783
+
784
+ /// <inheritdoc />
785
+ /// <remarks>Consider using <see cref=""Equals({ _quantity . Name } , { _valueType } , ComparisonType)""/> for safely comparing floating point values.</remarks>
786
+ public override bool Equals(object obj)
787
+ {{
788
+ if (obj is null || !(obj is { _quantity . Name } obj{ _quantity . Name } ))
789
+ return false;
790
+ return Equals(obj{ _quantity . Name } );
791
+ }}
792
+
793
+ /// <inheritdoc />
794
+ /// <remarks>Consider using <see cref=""Equals({ _quantity . Name } , { _valueType } , ComparisonType)""/> for safely comparing floating point values.</remarks>
795
+ public bool Equals({ _quantity . Name } other)
796
+ {{
797
+ if (Value.IsDecimal)
798
+ return other.Value.Equals(this.GetValueAs(other.Unit));
799
+ if (other.Value.IsDecimal)
800
+ return Value.Equals(other.GetValueAs(this.Unit));
801
+ return this.Unit == other.Unit && this.Value.Equals(other.Value);
767
802
}}
768
803
769
804
/// <summary>
@@ -806,13 +841,13 @@ public int CompareTo({_quantity.Name} other)
806
841
/// <param name=""tolerance"">The absolute or relative tolerance value. Must be greater than or equal to 0.</param>
807
842
/// <param name=""comparisonType"">The comparison type: either relative or absolute.</param>
808
843
/// <returns>True if the absolute difference between the two values is not greater than the specified relative or absolute tolerance.</returns>
809
- public bool Equals({ _quantity . Name } other, double tolerance, ComparisonType comparisonType)
844
+ public bool Equals({ _quantity . Name } other, { _valueType } tolerance, ComparisonType comparisonType)
810
845
{{
811
846
if (tolerance < 0)
812
847
throw new ArgumentOutOfRangeException(""tolerance"", ""Tolerance must be greater than or equal to 0."");
813
848
814
- double thisValue = (double) this.Value;
815
- double otherValueInThisUnits = other.As(this.Unit);
849
+ { _valueType } thisValue = this.Value;
850
+ { _valueType } otherValueInThisUnits = other.As(this.Unit);
816
851
817
852
return UnitsNet.Comparison.Equals(thisValue, otherValueInThisUnits, tolerance, comparisonType);
818
853
}}
@@ -823,7 +858,7 @@ public bool Equals({_quantity.Name} other, double tolerance, ComparisonType comp
823
858
/// <returns>A hash code for the current { _quantity . Name } .</returns>
824
859
public override int GetHashCode()
825
860
{{
826
- return new {{ Info.Name, Value, Unit }} .GetHashCode();
861
+ return Info.Name.GetHashCode();
827
862
}}
828
863
829
864
#endregion
@@ -839,17 +874,30 @@ private void GenerateConversionMethods()
839
874
/// Convert to the unit representation <paramref name=""unit"" />.
840
875
/// </summary>
841
876
/// <returns>Value converted to the specified unit.</returns>
842
- public double As({ _unitEnumName } unit)
877
+ public { _valueType } As({ _unitEnumName } unit)
843
878
{{
844
- if (Unit == unit)
845
- return Convert.ToDouble( Value) ;
879
+ if(Unit == unit)
880
+ return Value;
846
881
847
- var converted = GetValueAs(unit);
848
- return Convert.ToDouble(converted);
882
+ return GetValueAs(unit);
849
883
}}
884
+ " ) ;
885
+
886
+ if ( _valueType == "decimal" )
887
+ {
888
+ Writer. WL ( $@ "
889
+
890
+ { _valueType } IQuantity<{ _unitEnumName } >.As({ _unitEnumName } unit)
891
+ {{
892
+ return ({ _valueType } )As(unit);
893
+ }}
894
+ " ) ;
895
+ }
896
+
897
+ Writer. WL ( $@ "
850
898
851
899
/// <inheritdoc cref=""IQuantity.As(UnitSystem)""/>
852
- public double As(UnitSystem unitSystem)
900
+ public { _valueType } As(UnitSystem unitSystem)
853
901
{{
854
902
if (unitSystem is null)
855
903
throw new ArgumentNullException(nameof(unitSystem));
@@ -862,14 +910,27 @@ public double As(UnitSystem unitSystem)
862
910
863
911
return As(firstUnitInfo.Value);
864
912
}}
913
+ " ) ;
914
+
915
+ if ( _valueType == "decimal" )
916
+ {
917
+ Writer. WL ( $@ "
918
+ /// <inheritdoc cref=""IQuantity.As(UnitSystem)""/>
919
+ { _valueType } IQuantity.As(UnitSystem unitSystem)
920
+ {{
921
+ return ({ _valueType } )As(unitSystem);
922
+ }}
923
+ " ) ;
924
+ }
865
925
926
+ Writer. WL ( $@ "
866
927
/// <inheritdoc />
867
- double IQuantity.As(Enum unit)
928
+ { _valueType } IQuantity.As(Enum unit)
868
929
{{
869
- if (!(unit is { _unitEnumName } unitAs { _unitEnumName } ))
930
+ if (!(unit is { _unitEnumName } typedUnit ))
870
931
throw new ArgumentException($""The given unit is of type {{unit.GetType()}}. Only {{typeof({ _unitEnumName } )}} is supported."", nameof(unit));
871
932
872
- return As(unitAs { _unitEnumName } );
933
+ return ( { _valueType } )As(typedUnit );
873
934
}}
874
935
875
936
/// <summary>
@@ -901,25 +962,25 @@ double IQuantity.As(Enum unit)
901
962
var converted = conversionFunction(this);
902
963
return ({ _quantity . Name } )converted;
903
964
}}
904
- else if (Unit != BaseUnit )
965
+ else if (Enum.IsDefined(typeof( { _unitEnumName } ), unit) )
905
966
{{
906
967
// Direct conversion to requested unit NOT found. Convert to BaseUnit, and then from BaseUnit to requested unit.
907
968
var inBaseUnits = ToUnit(BaseUnit);
908
969
return inBaseUnits.ToUnit(unit);
909
970
}}
910
971
else
911
972
{{
912
- throw new NotImplementedException ($""Can not convert {{Unit}} to {{unit}}."");
973
+ throw new NotSupportedException ($""Can not convert {{Unit}} to {{unit}}."");
913
974
}}
914
975
}}
915
976
916
977
/// <inheritdoc />
917
978
IQuantity IQuantity.ToUnit(Enum unit)
918
979
{{
919
- if (!(unit is { _unitEnumName } unitAs { _unitEnumName } ))
980
+ if (!(unit is { _unitEnumName } typedUnit ))
920
981
throw new ArgumentException($""The given unit is of type {{unit.GetType()}}. Only {{typeof({ _unitEnumName } )}} is supported."", nameof(unit));
921
982
922
- return ToUnit(unitAs { _unitEnumName } , DefaultConversionFunctions);
983
+ return ToUnit(typedUnit , DefaultConversionFunctions);
923
984
}}
924
985
925
986
/// <inheritdoc cref=""IQuantity.ToUnit(UnitSystem)""/>
0 commit comments