@@ -25,7 +25,7 @@ public QuantityGenerator(Quantity quantity)
2525 throw new ArgumentException ( $ "No unit found with SingularName equal to BaseUnit [{ _quantity . BaseUnit } ]. This unit must be defined.",
2626 nameof ( quantity ) ) ;
2727
28- _valueType = quantity . ValueType ;
28+ _valueType = "QuantityValue" ; // quantity.ValueType;
2929 _unitEnumName = $ "{ quantity . Name } Unit";
3030
3131 BaseDimensions baseDimensions = quantity . BaseDimensions ;
@@ -77,14 +77,14 @@ public partial struct {_quantity.Name} : IQuantity<{_unitEnumName}>, ");
7777 Writer . W ( "IDecimalQuantity, " ) ;
7878 }
7979
80- Writer . WL ( $ "IComparable, IComparable<{ _quantity . Name } >, IConvertible, IFormattable") ;
80+ Writer . WL ( $ "IEquatable< { _quantity . Name } >, IComparable, IComparable<{ _quantity . Name } >, IConvertible, IFormattable") ;
8181 Writer . WL ( $@ "
8282 {{
8383 /// <summary>
8484 /// The numeric value this quantity was constructed with.
8585 /// </summary>
8686 [DataMember(Name = ""Value"", Order = 0)]
87- private readonly { _quantity . ValueType } _value;
87+ private readonly { _valueType } _value;
8888
8989 /// <summary>
9090 /// The unit this quantity was constructed with.
@@ -176,9 +176,9 @@ private void GenerateInstanceConstructors()
176176 /// <param name=""value"">The numeric value to construct this quantity with.</param>
177177 /// <param name=""unit"">The unit representation to construct this quantity with.</param>
178178 /// <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)
180180 {{" ) ;
181- Writer . WL ( _quantity . ValueType == "double"
181+ Writer . WL ( _valueType == "double"
182182 ? @"
183183 _value = Guard.EnsureValidNumber(value, nameof(value));"
184184 : @"
@@ -203,7 +203,7 @@ private void GenerateInstanceConstructors()
203203 var firstUnitInfo = unitInfos.FirstOrDefault();
204204" ) ;
205205
206- Writer . WL ( _quantity . ValueType == "double"
206+ Writer . WL ( _valueType == "double"
207207 ? @"
208208 _value = Guard.EnsureValidNumber(value, nameof(value));"
209209 : @"
@@ -262,15 +262,15 @@ private void GenerateProperties()
262262 public { _valueType } Value => _value;
263263" ) ;
264264
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;
269268" ) ;
269+ // Need to provide explicit interface implementation for decimal quantities like Information
270270 if ( _quantity . ValueType == "decimal" )
271271 Writer . WL ( @"
272272 /// <inheritdoc cref=""IDecimalQuantity.Value""/>
273- decimal IDecimalQuantity.Value => _value;
273+ decimal IDecimalQuantity.Value => (decimal) _value;
274274" ) ;
275275
276276 Writer . WL ( $@ "
@@ -306,11 +306,11 @@ private void GenerateConversionProperties()
306306
307307 Writer . WL ( $@ "
308308 /// <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 } ""/>
310310 /// </summary>" ) ;
311311 Writer . WLIfText ( 2 , GetObsoleteAttributeOrNull ( unit ) ) ;
312312 Writer . WL ( $@ "
313- public double { unit . PluralName } => As({ _unitEnumName } .{ unit . SingularName } );
313+ public { _valueType } { unit . PluralName } => As({ _unitEnumName } .{ unit . SingularName } );
314314" ) ;
315315 }
316316
@@ -426,7 +426,7 @@ private void GenerateStaticFactoryMethods()
426426 /// <exception cref=""ArgumentException"">If value is NaN or Infinity.</exception>" ) ;
427427 Writer. WLIfText ( 2 , GetObsoleteAttributeOrNull ( unit ) ) ;
428428 Writer. WL ( $@ "
429- public static { _quantity . Name } From{ unit . PluralName } (QuantityValue { valueParamName } )
429+ public static { _quantity . Name } From{ unit . PluralName } ({ _valueType } { valueParamName } )
430430 {{
431431 { _valueType } value = ({ _valueType } ) { valueParamName } ;
432432 return new { _quantity . Name } (value, { _unitEnumName } .{ unit . SingularName } );
@@ -651,7 +651,7 @@ private void GenerateArithmeticOperators()
651651 }}
652652
653653 /// <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)
655655 {{
656656 return left.{ _baseUnit . PluralName } / right.{ _baseUnit . PluralName } ;
657657 }}
@@ -679,15 +679,15 @@ private void GenerateLogarithmicArithmeticOperators()
679679 {{
680680 // Logarithmic addition
681681 // 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);
683683 }}
684684
685685 /// <summary>Get <see cref=""{ _quantity . Name } ""/> from logarithmic subtraction of two <see cref=""{ _quantity . Name } ""/>.</summary>
686686 public static { _quantity . Name } operator -({ _quantity . Name } left, { _quantity . Name } right)
687687 {{
688688 // Logarithmic subtraction
689689 // 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);
691691 }}
692692
693693 /// <summary>Get <see cref=""{ _quantity . Name } ""/> from logarithmic multiplication of value and <see cref=""{ _quantity . Name } ""/>.</summary>
@@ -751,6 +751,19 @@ private void GenerateEqualityAndComparison()
751751 return left.Value > right.GetValueAs(left.Unit);
752752 }}
753753
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+
754767 /// <inheritdoc />
755768 public int CompareTo(object obj)
756769 {{
@@ -763,7 +776,29 @@ public int CompareTo(object obj)
763776 /// <inheritdoc />
764777 public int CompareTo({ _quantity . Name } other)
765778 {{
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);
767802 }}
768803
769804 /// <summary>
@@ -806,13 +841,13 @@ public int CompareTo({_quantity.Name} other)
806841 /// <param name=""tolerance"">The absolute or relative tolerance value. Must be greater than or equal to 0.</param>
807842 /// <param name=""comparisonType"">The comparison type: either relative or absolute.</param>
808843 /// <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)
810845 {{
811846 if (tolerance < 0)
812847 throw new ArgumentOutOfRangeException(""tolerance"", ""Tolerance must be greater than or equal to 0."");
813848
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);
816851
817852 return UnitsNet.Comparison.Equals(thisValue, otherValueInThisUnits, tolerance, comparisonType);
818853 }}
@@ -823,7 +858,7 @@ public bool Equals({_quantity.Name} other, double tolerance, ComparisonType comp
823858 /// <returns>A hash code for the current { _quantity . Name } .</returns>
824859 public override int GetHashCode()
825860 {{
826- return new {{ Info.Name, Value, Unit }} .GetHashCode();
861+ return Info.Name.GetHashCode();
827862 }}
828863
829864 #endregion
@@ -839,17 +874,30 @@ private void GenerateConversionMethods()
839874 /// Convert to the unit representation <paramref name=""unit"" />.
840875 /// </summary>
841876 /// <returns>Value converted to the specified unit.</returns>
842- public double As({ _unitEnumName } unit)
877+ public { _valueType } As({ _unitEnumName } unit)
843878 {{
844- if (Unit == unit)
845- return Convert.ToDouble( Value) ;
879+ if(Unit == unit)
880+ return Value;
846881
847- var converted = GetValueAs(unit);
848- return Convert.ToDouble(converted);
882+ return GetValueAs(unit);
849883 }}
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 ( $@ "
850898
851899 /// <inheritdoc cref=""IQuantity.As(UnitSystem)""/>
852- public double As(UnitSystem unitSystem)
900+ public { _valueType } As(UnitSystem unitSystem)
853901 {{
854902 if (unitSystem is null)
855903 throw new ArgumentNullException(nameof(unitSystem));
@@ -862,14 +910,27 @@ public double As(UnitSystem unitSystem)
862910
863911 return As(firstUnitInfo.Value);
864912 }}
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+ }
865925
926+ Writer. WL ( $@ "
866927 /// <inheritdoc />
867- double IQuantity.As(Enum unit)
928+ { _valueType } IQuantity.As(Enum unit)
868929 {{
869- if (!(unit is { _unitEnumName } unitAs { _unitEnumName } ))
930+ if (!(unit is { _unitEnumName } typedUnit ))
870931 throw new ArgumentException($""The given unit is of type {{unit.GetType()}}. Only {{typeof({ _unitEnumName } )}} is supported."", nameof(unit));
871932
872- return As(unitAs { _unitEnumName } );
933+ return ( { _valueType } )As(typedUnit );
873934 }}
874935
875936 /// <summary>
@@ -901,25 +962,25 @@ double IQuantity.As(Enum unit)
901962 var converted = conversionFunction(this);
902963 return ({ _quantity . Name } )converted;
903964 }}
904- else if (Unit != BaseUnit )
965+ else if (Enum.IsDefined(typeof( { _unitEnumName } ), unit) )
905966 {{
906967 // Direct conversion to requested unit NOT found. Convert to BaseUnit, and then from BaseUnit to requested unit.
907968 var inBaseUnits = ToUnit(BaseUnit);
908969 return inBaseUnits.ToUnit(unit);
909970 }}
910971 else
911972 {{
912- throw new NotImplementedException ($""Can not convert {{Unit}} to {{unit}}."");
973+ throw new NotSupportedException ($""Can not convert {{Unit}} to {{unit}}."");
913974 }}
914975 }}
915976
916977 /// <inheritdoc />
917978 IQuantity IQuantity.ToUnit(Enum unit)
918979 {{
919- if (!(unit is { _unitEnumName } unitAs { _unitEnumName } ))
980+ if (!(unit is { _unitEnumName } typedUnit ))
920981 throw new ArgumentException($""The given unit is of type {{unit.GetType()}}. Only {{typeof({ _unitEnumName } )}} is supported."", nameof(unit));
921982
922- return ToUnit(unitAs { _unitEnumName } , DefaultConversionFunctions);
983+ return ToUnit(typedUnit , DefaultConversionFunctions);
923984 }}
924985
925986 /// <inheritdoc cref=""IQuantity.ToUnit(UnitSystem)""/>
0 commit comments