diff --git a/Source/Meadow.Units/Angle.cs b/Source/Meadow.Units/Angle.cs
index 68c311e..9b5026c 100644
--- a/Source/Meadow.Units/Angle.cs
+++ b/Source/Meadow.Units/Angle.cs
@@ -1,429 +1,437 @@
-using System;
+using Meadow.Units.Conversions;
+using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
-using Meadow.Units.Conversions;
-namespace Meadow.Units
+namespace Meadow.Units;
+
+///
+/// Represents Angle
+///
+[Serializable]
+[ImmutableObject(true)]
+[StructLayout(LayoutKind.Sequential)]
+public struct Angle :
+ IComparable, IFormattable, IConvertible,
+ IEquatable, IComparable
{
+ private static Angle? _zero;
+
+ ///
+ /// Gets an angle of 0 degrees
+ ///
+ public static Angle Zero => _zero ?? (_zero = new Angle(0, UnitType.Degrees)).Value;
+
///
- /// Represents Angle
+ /// Creates a new `Angle` object.
///
- [Serializable]
- [ImmutableObject(true)]
- [StructLayout(LayoutKind.Sequential)]
- public struct Angle :
- IComparable, IFormattable, IConvertible,
- IEquatable, IComparable
+ /// The Angle value.
+ /// Degrees by default.
+ public Angle(double value, UnitType type = UnitType.Degrees)
{
- ///
- /// Creates a new `Angle` object.
- ///
- /// The Angle value.
- /// Degrees by default.
- public Angle(double value, UnitType type = UnitType.Degrees)
- {
- Value = AngleConversions.Convert(value, type, UnitType.Degrees);
- }
+ Value = AngleConversions.Convert(value, type, UnitType.Degrees);
+ }
- ///
- /// Creates a new `Angle` object from an existing angle object
- ///
- ///
- public Angle(Angle angle)
- {
- Value = angle.Value;
- }
+ ///
+ /// Creates a new `Angle` object from an existing angle object
+ ///
+ ///
+ public Angle(Angle angle)
+ {
+ Value = angle.Value;
+ }
- ///
- /// Internal canonical value.
- ///
- private readonly double Value;
+ ///
+ /// Internal canonical value.
+ ///
+ private readonly double Value;
+ ///
+ /// The type of units available to describe the Angle.
+ ///
+ public enum UnitType
+ {
///
- /// The type of units available to describe the Angle.
+ /// Revolutions
///
- public enum UnitType
- {
- ///
- /// Revolutions
- ///
- Revolutions,
- ///
- /// Degrees
- ///
- Degrees,
- ///
- /// Radians
- ///
- Radians,
- ///
- /// Gradians
- ///
- Gradians,
- ///
- /// Minutes
- ///
- Minutes,
- ///
- /// Seconds
- ///
- Seconds
- }
-
+ Revolutions,
///
- /// Get angle in revolutions
+ /// Degrees
///
- public double Revolutions => From(UnitType.Revolutions);
-
+ Degrees,
///
- /// Get angle in degrees
+ /// Radians
///
- public double Degrees => From(UnitType.Degrees);
-
+ Radians,
///
- /// Get angle in radians
+ /// Gradians
///
- public double Radians => From(UnitType.Radians);
-
+ Gradians,
///
- /// Get angle in gradians
+ /// Minutes
///
- public double Gradians => From(UnitType.Gradians);
-
+ Minutes,
///
- /// Get angle in minutes
+ /// Seconds
///
- public double Minutes => From(UnitType.Minutes);
+ Seconds
+ }
- ///
- /// Get angle in seconds
- ///
- public double Seconds => From(UnitType.Seconds);
+ ///
+ /// Get angle in revolutions
+ ///
+ public double Revolutions => From(UnitType.Revolutions);
- ///
- /// Get a double value for a specific unit
- ///
- /// unit to covert to
- /// the converted value
- [Pure] public double From(UnitType convertTo)
- {
- return ConvertTo360(AngleConversions.Convert(Value, UnitType.Degrees, convertTo));
- }
+ ///
+ /// Get angle in degrees
+ ///
+ public double Degrees => From(UnitType.Degrees);
- ///
- /// Compare to another Angle object
- ///
- /// The object to compare
- /// true if equal
- [Pure] public override bool Equals(object obj)
- {
- if (obj is null) { return false; }
- if (Equals(this, obj)) { return true; }
- return obj.GetType() == GetType() && Equals((Angle)obj);
- }
+ ///
+ /// Get angle in radians
+ ///
+ public double Radians => From(UnitType.Radians);
- ///
- /// Get hash of object
- ///
- /// int32 hash value
- [Pure] public override int GetHashCode() => Value.GetHashCode();
-
- // implicit conversions
- //[Pure] public static implicit operator Angle(ushort value) => new Angle(value);
- //[Pure] public static implicit operator Angle(short value) => new Angle(value);
- //[Pure] public static implicit operator Angle(uint value) => new Angle(value);
- //[Pure] public static implicit operator Angle(long value) => new Angle(value);
- //[Pure] public static implicit operator Angle(int value) => new Angle(value);
- //[Pure] public static implicit operator Angle(float value) => new Angle(value);
- //[Pure] public static implicit operator Angle(double value) => new Angle(value);
- //[Pure] public static implicit operator Angle(decimal value) => new Angle((double)value);
-
- // Comparison
- ///
- /// Compare to another Angle object
- ///
- /// The object to compare
- /// true if equal
- [Pure] public bool Equals(Angle other) => Value == other.Value;
+ ///
+ /// Get angle in gradians
+ ///
+ public double Gradians => From(UnitType.Gradians);
- ///
- /// Equals operator to compare two Angle objects
- ///
- /// left value
- /// right value
- /// true if equal
- [Pure] public static bool operator ==(Angle left, Angle right) => Equals(left.Value, right.Value);
+ ///
+ /// Get angle in minutes
+ ///
+ public double Minutes => From(UnitType.Minutes);
- ///
- /// Not equals operator to compare two Angle objects
- ///
- /// left value
- /// right value
- /// true if not equal
- [Pure] public static bool operator !=(Angle left, Angle right) => !Equals(left.Value, right.Value);
+ ///
+ /// Get angle in seconds
+ ///
+ public double Seconds => From(UnitType.Seconds);
- ///
- /// Compare to another Angle object
- ///
- ///
- /// 0 if equal
- [Pure] public int CompareTo(Angle other) => Equals(Value, other.Value) ? 0 : Value.CompareTo(other.Value);
+ ///
+ /// Get a double value for a specific unit
+ ///
+ /// unit to covert to
+ /// the converted value
+ [Pure]
+ public double From(UnitType convertTo)
+ {
+ return ConvertTo360(AngleConversions.Convert(Value, UnitType.Degrees, convertTo));
+ }
- ///
- /// Less than operator to compare two Angle objects
- ///
- /// left value
- /// right value
- /// true if left is less than right
- [Pure] public static bool operator <(Angle left, Angle right) => Comparer.Default.Compare(left.Value, right.Value) < 0;
+ ///
+ /// Compare to another Angle object
+ ///
+ /// The object to compare
+ /// true if equal
+ [Pure]
+ public override bool Equals(object obj)
+ {
+ if (obj is null) { return false; }
+ if (Equals(this, obj)) { return true; }
+ return obj.GetType() == GetType() && Equals((Angle)obj);
+ }
- ///
- /// Greater than operator to compare two Angle objects
- ///
- /// left value
- /// right value
- /// true if left is greater than right
- [Pure] public static bool operator >(Angle left, Angle right) => Comparer.Default.Compare(left.Value, right.Value) > 0;
+ ///
+ /// Get hash of object
+ ///
+ /// int32 hash value
+ [Pure] public override int GetHashCode() => Value.GetHashCode();
+
+ // implicit conversions
+ //[Pure] public static implicit operator Angle(ushort value) => new Angle(value);
+ //[Pure] public static implicit operator Angle(short value) => new Angle(value);
+ //[Pure] public static implicit operator Angle(uint value) => new Angle(value);
+ //[Pure] public static implicit operator Angle(long value) => new Angle(value);
+ //[Pure] public static implicit operator Angle(int value) => new Angle(value);
+ //[Pure] public static implicit operator Angle(float value) => new Angle(value);
+ //[Pure] public static implicit operator Angle(double value) => new Angle(value);
+ //[Pure] public static implicit operator Angle(decimal value) => new Angle((double)value);
+
+ // Comparison
+ ///
+ /// Compare to another Angle object
+ ///
+ /// The object to compare
+ /// true if equal
+ [Pure] public bool Equals(Angle other) => Value == other.Value;
- ///
- /// Less than or equal operator to compare two Angle objects
- ///
- /// left value
- /// right value
- /// true if left is less than or equal to right
- [Pure] public static bool operator <=(Angle left, Angle right) => Comparer.Default.Compare(left.Value, right.Value) <= 0;
+ ///
+ /// Equals operator to compare two Angle objects
+ ///
+ /// left value
+ /// right value
+ /// true if equal
+ [Pure] public static bool operator ==(Angle left, Angle right) => Equals(left.Value, right.Value);
- ///
- /// Greater than or equal operator to compare two Angle objects
- ///
- /// left value
- /// right value
- /// true if left is greater than or equal to right
- [Pure] public static bool operator >=(Angle left, Angle right) => Comparer.Default.Compare(left.Value, right.Value) >= 0;
+ ///
+ /// Not equals operator to compare two Angle objects
+ ///
+ /// left value
+ /// right value
+ /// true if not equal
+ [Pure] public static bool operator !=(Angle left, Angle right) => !Equals(left.Value, right.Value);
- ///
- /// Helper method to ensure mathematical results 'wrap' correctly at 0/360 degrees.
- ///
- /// proper result in the range of [0,360)
- private static double ConvertTo360(double value)
- {
- value %= 360;
- if (value < 0)
- value += 360;
- return value;
- }
-
- // Math
- ///
- /// Addition operator to add two Angle objects
- ///
- /// left value
- /// right value
- /// A new Angle object with a value of left + right
- [Pure] public static Angle operator +(Angle left, Angle right) => new (ConvertTo360(left.Value + right.Value));
+ ///
+ /// Compare to another Angle object
+ ///
+ ///
+ /// 0 if equal
+ [Pure] public int CompareTo(Angle other) => Equals(Value, other.Value) ? 0 : Value.CompareTo(other.Value);
- ///
- /// Subtraction operator to subtract two Angle objects
- ///
- /// left value
- /// right value
- /// A new Angle object with a value of left - right
- [Pure] public static Angle operator -(Angle left, Angle right) => new (ConvertTo360(left.Value - right.Value));
+ ///
+ /// Less than operator to compare two Angle objects
+ ///
+ /// left value
+ /// right value
+ /// true if left is less than right
+ [Pure] public static bool operator <(Angle left, Angle right) => Comparer.Default.Compare(left.Value, right.Value) < 0;
- ///
- /// Multiplication operator to multiply by a double
- ///
- /// object to multiply
- /// operand to multiply object
- /// A new Angle object with a value of value multiplied by the operand
- [Pure] public static Angle operator *(Angle value, double operand) => new (ConvertTo360(value.Value * operand));
+ ///
+ /// Greater than operator to compare two Angle objects
+ ///
+ /// left value
+ /// right value
+ /// true if left is greater than right
+ [Pure] public static bool operator >(Angle left, Angle right) => Comparer.Default.Compare(left.Value, right.Value) > 0;
- ///
- /// Division operator to divide by a double
- ///
- /// object to be divided
- /// operand to divide object
- /// A new Angle object with a value of value divided by the operand
- [Pure] public static Angle operator /(Angle value, double operand) => new (ConvertTo360(value.Value / operand));
+ ///
+ /// Less than or equal operator to compare two Angle objects
+ ///
+ /// left value
+ /// right value
+ /// true if left is less than or equal to right
+ [Pure] public static bool operator <=(Angle left, Angle right) => Comparer.Default.Compare(left.Value, right.Value) <= 0;
- ///
- /// Returns the absolute value of the
- ///
- ///
- [Pure] public Angle Abs() { return new Angle(Math.Abs(this.Value)); }
+ ///
+ /// Greater than or equal operator to compare two Angle objects
+ ///
+ /// left value
+ /// right value
+ /// true if left is greater than or equal to right
+ [Pure] public static bool operator >=(Angle left, Angle right) => Comparer.Default.Compare(left.Value, right.Value) >= 0;
- ///
- /// Get a string representation of the object
- ///
- /// A string representing the object
- [Pure] public override string ToString() => Value.ToString();
+ ///
+ /// Helper method to ensure mathematical results 'wrap' correctly at 0/360 degrees.
+ ///
+ /// proper result in the range of [0,360)
+ private static double ConvertTo360(double value)
+ {
+ value %= 360;
+ if (value < 0)
+ value += 360;
+ return value;
+ }
- ///
- /// Get a string representation of the object
- ///
- /// format
- /// format provider
- /// A string representing the object
- [Pure] public string ToString(string format, IFormatProvider formatProvider) => Value.ToString(format, formatProvider);
+ ///
+ /// Addition operator to add two Angle objects
+ ///
+ /// left value
+ /// right value
+ /// A new Angle object with a value of left + right
+ [Pure] public static Angle operator +(Angle left, Angle right) => new(ConvertTo360(left.Value + right.Value));
- // IComparable
- ///
- /// Compare to another Angle object
- ///
- /// The other Angle cast to object
- /// 0 if equal
- [Pure] public int CompareTo(object obj) => Value.CompareTo(obj);
+ ///
+ /// Subtraction operator to subtract two Angle objects
+ ///
+ /// left value
+ /// right value
+ /// A new Angle object with a value of left - right
+ [Pure] public static Angle operator -(Angle left, Angle right) => new(ConvertTo360(left.Value - right.Value));
- ///
- /// Get type code of object
- ///
- /// The TypeCode
- [Pure] public TypeCode GetTypeCode() => Value.GetTypeCode();
+ ///
+ /// Multiplication operator to multiply by a double
+ ///
+ /// object to multiply
+ /// operand to multiply object
+ /// A new Angle object with a value of value multiplied by the operand
+ [Pure] public static Angle operator *(Angle value, double operand) => new(ConvertTo360(value.Value * operand));
- ///
- /// Convert to boolean
- ///
- /// format provider
- /// bool representation of the object
- [Pure] public bool ToBoolean(IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
+ ///
+ /// Division operator to divide by a double
+ ///
+ /// object to be divided
+ /// operand to divide object
+ /// A new Angle object with a value of value divided by the operand
+ [Pure] public static Angle operator /(Angle value, double operand) => new(ConvertTo360(value.Value / operand));
- ///
- /// Convert to byte
- ///
- /// format provider
- /// byte representation of the object
- [Pure] public byte ToByte(IFormatProvider provider) => ((IConvertible)Value).ToByte(provider);
+ ///
+ /// Returns the absolute value of the
+ ///
+ ///
+ [Pure] public Angle Abs() { return new Angle(Math.Abs(this.Value)); }
- ///
- /// Convert to char
- ///
- /// format provider
- /// char representation of the object
- [Pure] public char ToChar(IFormatProvider provider) => ((IConvertible)Value).ToChar(provider);
+ ///
+ /// Get a string representation of the object
+ ///
+ /// A string representing the object
+ [Pure] public override string ToString() => Value.ToString();
- ///
- /// Convert to DateTime
- ///
- /// format provider
- /// DateTime representation of the object
- [Pure] public DateTime ToDateTime(IFormatProvider provider) => ((IConvertible)Value).ToDateTime(provider);
+ ///
+ /// Get a string representation of the object
+ ///
+ /// format
+ /// format provider
+ /// A string representing the object
+ [Pure] public string ToString(string format, IFormatProvider formatProvider) => Value.ToString(format, formatProvider);
- ///
- /// Convert to Decimal
- ///
- /// format provider
- /// Decimal representation of the object
- [Pure] public decimal ToDecimal(IFormatProvider provider) => ((IConvertible)Value).ToDecimal(provider);
+ // IComparable
+ ///
+ /// Compare to another Angle object
+ ///
+ /// The other Angle cast to object
+ /// 0 if equal
+ [Pure] public int CompareTo(object obj) => Value.CompareTo(obj);
- ///
- /// Convert to double
- ///
- /// format provider
- /// double representation of the object
- [Pure] public double ToDouble(IFormatProvider provider) => Value;
+ ///
+ /// Get type code of object
+ ///
+ /// The TypeCode
+ [Pure] public TypeCode GetTypeCode() => Value.GetTypeCode();
- ///
- /// Convert to in16
- ///
- /// format provider
- /// int16 representation of the object
- [Pure] public short ToInt16(IFormatProvider provider) => ((IConvertible)Value).ToInt16(provider);
+ ///
+ /// Convert to boolean
+ ///
+ /// format provider
+ /// bool representation of the object
+ [Pure] public bool ToBoolean(IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
- ///
- /// Convert to int32
- ///
- /// format provider
- /// int32 representation of the object
- [Pure] public int ToInt32(IFormatProvider provider) => ((IConvertible)Value).ToInt32(provider);
+ ///
+ /// Convert to byte
+ ///
+ /// format provider
+ /// byte representation of the object
+ [Pure] public byte ToByte(IFormatProvider provider) => ((IConvertible)Value).ToByte(provider);
- ///
- /// Convert to int64
- ///
- /// format provider
- /// int64 representation of the object
- [Pure] public long ToInt64(IFormatProvider provider) => ((IConvertible)Value).ToInt64(provider);
+ ///
+ /// Convert to char
+ ///
+ /// format provider
+ /// char representation of the object
+ [Pure] public char ToChar(IFormatProvider provider) => ((IConvertible)Value).ToChar(provider);
- ///
- /// Convert to sbyte
- ///
- /// format provider
- /// sbyte representation of the object
- [Pure] public sbyte ToSByte(IFormatProvider provider) => ((IConvertible)Value).ToSByte(provider);
+ ///
+ /// Convert to DateTime
+ ///
+ /// format provider
+ /// DateTime representation of the object
+ [Pure] public DateTime ToDateTime(IFormatProvider provider) => ((IConvertible)Value).ToDateTime(provider);
- ///
- /// Convert to float
- ///
- /// format provider
- /// float representation of the object
- [Pure] public float ToSingle(IFormatProvider provider) => ((IConvertible)Value).ToSingle(provider);
+ ///
+ /// Convert to Decimal
+ ///
+ /// format provider
+ /// Decimal representation of the object
+ [Pure] public decimal ToDecimal(IFormatProvider provider) => ((IConvertible)Value).ToDecimal(provider);
- ///
- /// Convert to string
- ///
- /// format provider
- /// string representation of the object
- [Pure] public string ToString(IFormatProvider provider) => Value.ToString(provider);
+ ///
+ /// Convert to double
+ ///
+ /// format provider
+ /// double representation of the object
+ [Pure] public double ToDouble(IFormatProvider provider) => Value;
- ///
- /// Convert to type
- ///
- /// conversion type
- /// format provider
- /// type representation of the object
- [Pure] public object ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)Value).ToType(conversionType, provider);
+ ///
+ /// Convert to in16
+ ///
+ /// format provider
+ /// int16 representation of the object
+ [Pure] public short ToInt16(IFormatProvider provider) => ((IConvertible)Value).ToInt16(provider);
- ///
- /// Convert to uint16
- ///
- /// format provider
- /// uint16 representation of the object
- [Pure] public ushort ToUInt16(IFormatProvider provider) => ((IConvertible)Value).ToUInt16(provider);
+ ///
+ /// Convert to int32
+ ///
+ /// format provider
+ /// int32 representation of the object
+ [Pure] public int ToInt32(IFormatProvider provider) => ((IConvertible)Value).ToInt32(provider);
- ///
- /// Convert to uint32
- ///
- /// format provider
- /// uint32 representation of the object
- [Pure] public uint ToUInt32(IFormatProvider provider) => ((IConvertible)Value).ToUInt32(provider);
+ ///
+ /// Convert to int64
+ ///
+ /// format provider
+ /// int64 representation of the object
+ [Pure] public long ToInt64(IFormatProvider provider) => ((IConvertible)Value).ToInt64(provider);
- ///
- /// Convert to uint64
- ///
- /// format provider
- /// uint64 representation of the object
- [Pure] public ulong ToUInt64(IFormatProvider provider) => ((IConvertible)Value).ToUInt64(provider);
+ ///
+ /// Convert to sbyte
+ ///
+ /// format provider
+ /// sbyte representation of the object
+ [Pure] public sbyte ToSByte(IFormatProvider provider) => ((IConvertible)Value).ToSByte(provider);
- ///
- /// Compare the default value to a double
- ///
- /// value to compare
- /// 0 if equal
- [Pure] public int CompareTo(double? other)
- {
- return (other is null) ? -1 : (Value).CompareTo(other.Value);
- }
+ ///
+ /// Convert to float
+ ///
+ /// format provider
+ /// float representation of the object
+ [Pure] public float ToSingle(IFormatProvider provider) => ((IConvertible)Value).ToSingle(provider);
- ///
- /// Compare the default value to a double
- ///
- /// value to compare
- /// 0 if equal
- [Pure] public bool Equals(double? other) => Value.Equals(other);
+ ///
+ /// Convert to string
+ ///
+ /// format provider
+ /// string representation of the object
+ [Pure] public string ToString(IFormatProvider provider) => Value.ToString(provider);
- ///
- /// Compare the default value to a double
- ///
- /// value to compare
- /// 0 if equal
- [Pure] public bool Equals(double other) => Value.Equals(other);
+ ///
+ /// Convert to type
+ ///
+ /// conversion type
+ /// format provider
+ /// type representation of the object
+ [Pure] public object ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)Value).ToType(conversionType, provider);
- ///
- /// Compare the default value to a double
- ///
- /// value to compare
- /// 0 if equal
- [Pure] public int CompareTo(double other) => Value.CompareTo(other);
+ ///
+ /// Convert to uint16
+ ///
+ /// format provider
+ /// uint16 representation of the object
+ [Pure] public ushort ToUInt16(IFormatProvider provider) => ((IConvertible)Value).ToUInt16(provider);
+
+ ///
+ /// Convert to uint32
+ ///
+ /// format provider
+ /// uint32 representation of the object
+ [Pure] public uint ToUInt32(IFormatProvider provider) => ((IConvertible)Value).ToUInt32(provider);
+
+ ///
+ /// Convert to uint64
+ ///
+ /// format provider
+ /// uint64 representation of the object
+ [Pure] public ulong ToUInt64(IFormatProvider provider) => ((IConvertible)Value).ToUInt64(provider);
+
+ ///
+ /// Compare the default value to a double
+ ///
+ /// value to compare
+ /// 0 if equal
+ [Pure]
+ public int CompareTo(double? other)
+ {
+ return (other is null) ? -1 : (Value).CompareTo(other.Value);
}
+
+ ///
+ /// Compare the default value to a double
+ ///
+ /// value to compare
+ /// 0 if equal
+ [Pure] public bool Equals(double? other) => Value.Equals(other);
+
+ ///
+ /// Compare the default value to a double
+ ///
+ /// value to compare
+ /// 0 if equal
+ [Pure] public bool Equals(double other) => Value.Equals(other);
+
+ ///
+ /// Compare the default value to a double
+ ///
+ /// value to compare
+ /// 0 if equal
+ [Pure] public int CompareTo(double other) => Value.CompareTo(other);
}
\ No newline at end of file
diff --git a/Source/Meadow.Units/Length.cs b/Source/Meadow.Units/Length.cs
index b9f1885..21f424d 100644
--- a/Source/Meadow.Units/Length.cs
+++ b/Source/Meadow.Units/Length.cs
@@ -1,460 +1,469 @@
-using System;
+using Meadow.Units.Conversions;
+using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
-using Meadow.Units.Conversions;
-namespace Meadow.Units
+namespace Meadow.Units;
+
+///
+/// Represents Length
+///
+[Serializable]
+[ImmutableObject(true)]
+[StructLayout(LayoutKind.Sequential)]
+public struct Length :
+ IComparable, IFormattable, IConvertible,
+ IEquatable, IComparable
{
+ private static Length? _zero;
+
///
- /// Represents Length
+ /// Gets a Length of 0
///
- [Serializable]
- [ImmutableObject(true)]
- [StructLayout(LayoutKind.Sequential)]
- public struct Length :
- IComparable, IFormattable, IConvertible,
- IEquatable, IComparable
- {
- ///
- /// Creates a new `Length` object.
- ///
- /// The Length value.
- /// Meters by default.
- public Length(double value, UnitType type = UnitType.Meters)
- {
- Value = LengthConversions.Convert(value, type, UnitType.Meters);
- }
+ public static Length Zero => _zero ?? (_zero = new Length(0, UnitType.Meters)).Value;
- ///
- /// Creates a new `Length` object from an existing Length object
- ///
- ///
- public Length(Length length)
- {
- this.Value = length.Value;
- }
+ ///
+ /// Creates a new `Length` object.
+ ///
+ /// The Length value.
+ /// Meters by default.
+ public Length(double value, UnitType type = UnitType.Meters)
+ {
+ Value = LengthConversions.Convert(value, type, UnitType.Meters);
+ }
- ///
- /// Internal canonical value.
- ///
- private readonly double Value;
+ ///
+ /// Creates a new `Length` object from an existing Length object
+ ///
+ ///
+ public Length(Length length)
+ {
+ this.Value = length.Value;
+ }
- ///
- /// The type of units available to describe the Length.
- ///
- public enum UnitType
- {
- ///
- /// Kilometers
- ///
- Kilometers,
- ///
- /// Meters
- ///
- Meters,
- ///
- /// Centimeters
- ///
- Centimeters,
- ///
- /// Decimeters
- ///
- Decimeters,
- ///
- /// Millimeters
- ///
- Millimeters,
- ///
- /// Microns
- ///
- Microns,
- ///
- /// Nanometers
- ///
- Nanometers,
- ///
- /// Miles
- ///
- Miles,
- ///
- /// Nautical miles
- ///
- NauticalMiles,
- ///
- /// Yards
- ///
- Yards,
- ///
- /// Feet
- ///
- Feet,
- ///
- /// Inches
- ///
- Inches,
- }
+ ///
+ /// Internal canonical value.
+ ///
+ private readonly double Value;
+ ///
+ /// The type of units available to describe the Length.
+ ///
+ public enum UnitType
+ {
///
- /// Get length value as Kilometers
+ /// Kilometers
///
- public double Kilometers => From(UnitType.Kilometers);
+ Kilometers,
///
- /// Get length value as Meters
+ /// Meters
///
- public double Meters => From(UnitType.Meters);
+ Meters,
///
- /// Get length value as Centimeters
+ /// Centimeters
///
- public double Centimeters => From(UnitType.Centimeters);
+ Centimeters,
///
- /// Get length value as Decimeters
+ /// Decimeters
///
- public double Decimeters => From(UnitType.Decimeters);
+ Decimeters,
///
- /// Get length value as Millimeters
+ /// Millimeters
///
- public double Millimeters => From(UnitType.Millimeters);
+ Millimeters,
///
- /// Get length value as Microns
+ /// Microns
///
- public double Microns => From(UnitType.Microns);
+ Microns,
///
- /// Get length value as Nanometers
+ /// Nanometers
///
- public double Nanometers => From(UnitType.Nanometers);
+ Nanometers,
///
- /// Get length value as Miles
+ /// Miles
///
- public double Miles => From(UnitType.Miles);
+ Miles,
///
- /// Get length value as NauticalMiles
+ /// Nautical miles
///
- public double NauticalMiles => From(UnitType.NauticalMiles);
+ NauticalMiles,
///
- /// Get length value as Yards
+ /// Yards
///
- public double Yards => From(UnitType.Yards);
+ Yards,
///
- /// Get length value as Feet
+ /// Feet
///
- public double Feet => From(UnitType.Feet);
+ Feet,
///
- /// Get length value as Inches
+ /// Inches
///
- public double Inches => From(UnitType.Inches);
+ Inches,
+ }
- ///
- /// Get a double value for a specific unit
- ///
- /// unit to covert to
- /// the converted value
- [Pure] public double From(UnitType convertTo)
- {
- return LengthConversions.Convert(Value, UnitType.Meters, convertTo);
- }
+ ///
+ /// Get length value as Kilometers
+ ///
+ public readonly double Kilometers => From(UnitType.Kilometers);
+ ///
+ /// Get length value as Meters
+ ///
+ public readonly double Meters => From(UnitType.Meters);
+ ///
+ /// Get length value as Centimeters
+ ///
+ public readonly double Centimeters => From(UnitType.Centimeters);
+ ///
+ /// Get length value as Decimeters
+ ///
+ public readonly double Decimeters => From(UnitType.Decimeters);
+ ///
+ /// Get length value as Millimeters
+ ///
+ public readonly double Millimeters => From(UnitType.Millimeters);
+ ///
+ /// Get length value as Microns
+ ///
+ public readonly double Microns => From(UnitType.Microns);
+ ///
+ /// Get length value as Nanometers
+ ///
+ public readonly double Nanometers => From(UnitType.Nanometers);
+ ///
+ /// Get length value as Miles
+ ///
+ public readonly double Miles => From(UnitType.Miles);
+ ///
+ /// Get length value as NauticalMiles
+ ///
+ public readonly double NauticalMiles => From(UnitType.NauticalMiles);
+ ///
+ /// Get length value as Yards
+ ///
+ public readonly double Yards => From(UnitType.Yards);
+ ///
+ /// Get length value as Feet
+ ///
+ public readonly double Feet => From(UnitType.Feet);
+ ///
+ /// Get length value as Inches
+ ///
+ public readonly double Inches => From(UnitType.Inches);
- ///
- /// Compare to another Length object
- ///
- /// The object to compare
- /// true if equal
- [Pure] public override bool Equals(object obj)
- {
- if (obj is null) { return false; }
- if (Equals(this, obj)) { return true; }
- return obj.GetType() == GetType() && Equals((Length)obj);
- }
+ ///
+ /// Get a double value for a specific unit
+ ///
+ /// unit to covert to
+ /// the converted value
+ [Pure]
+ public readonly double From(UnitType convertTo)
+ {
+ return LengthConversions.Convert(Value, UnitType.Meters, convertTo);
+ }
- ///
- /// Get hash of object
- ///
- /// int32 hash value
- [Pure] public override int GetHashCode() => Value.GetHashCode();
-
- // implicit conversions
- //[Pure] public static implicit operator Length(ushort value) => new Length(value);
- //[Pure] public static implicit operator Length(short value) => new Length(value);
- //[Pure] public static implicit operator Length(uint value) => new Length(value);
- //[Pure] public static implicit operator Length(long value) => new Length(value);
- //[Pure] public static implicit operator Length(int value) => new Length(value);
- //[Pure] public static implicit operator Length(float value) => new Length(value);
- //[Pure] public static implicit operator Length(double value) => new Length(value);
- //[Pure] public static implicit operator Length(decimal value) => new Length((double)value);
-
- // Comparison
- ///
- /// Compare to another Length object
- ///
- /// The object to compare
- /// true if equal
- [Pure] public bool Equals(Length other) => Value == other.Value;
+ ///
+ /// Compare to another Length object
+ ///
+ /// The object to compare
+ /// true if equal
+ [Pure]
+ public override readonly bool Equals(object obj)
+ {
+ if (obj is null) { return false; }
+ if (Equals(this, obj)) { return true; }
+ return obj.GetType() == GetType() && Equals((Length)obj);
+ }
- ///
- /// Equals operator to compare two Length objects
- ///
- /// left value
- /// right value
- /// true if equal
- [Pure] public static bool operator ==(Length left, Length right) => Equals(left.Value, right.Value);
+ ///
+ /// Get hash of object
+ ///
+ /// int32 hash value
+ [Pure] public override readonly int GetHashCode() => Value.GetHashCode();
+
+ // implicit conversions
+ //[Pure] public static implicit operator Length(ushort value) => new Length(value);
+ //[Pure] public static implicit operator Length(short value) => new Length(value);
+ //[Pure] public static implicit operator Length(uint value) => new Length(value);
+ //[Pure] public static implicit operator Length(long value) => new Length(value);
+ //[Pure] public static implicit operator Length(int value) => new Length(value);
+ //[Pure] public static implicit operator Length(float value) => new Length(value);
+ //[Pure] public static implicit operator Length(double value) => new Length(value);
+ //[Pure] public static implicit operator Length(decimal value) => new Length((double)value);
+
+ // Comparison
+ ///
+ /// Compare to another Length object
+ ///
+ /// The object to compare
+ /// true if equal
+ [Pure] public readonly bool Equals(Length other) => Value == other.Value;
- ///
- /// Not equals operator to compare two Length objects
- ///
- /// left value
- /// right value
- /// true if not equal
- [Pure] public static bool operator !=(Length left, Length right) => !Equals(left.Value, right.Value);
+ ///
+ /// Equals operator to compare two Length objects
+ ///
+ /// left value
+ /// right value
+ /// true if equal
+ [Pure] public static bool operator ==(Length left, Length right) => Equals(left.Value, right.Value);
- ///
- /// Compare to another Length object
- ///
- ///
- /// 0 if equal
- [Pure] public int CompareTo(Length other) => Equals(Value, other.Value) ? 0 : Value.CompareTo(other.Value);
+ ///
+ /// Not equals operator to compare two Length objects
+ ///
+ /// left value
+ /// right value
+ /// true if not equal
+ [Pure] public static bool operator !=(Length left, Length right) => !Equals(left.Value, right.Value);
- ///
- /// Less than operator to compare two Length objects
- ///
- /// left value
- /// right value
- /// true if left is less than right
- [Pure] public static bool operator <(Length left, Length right) => Comparer.Default.Compare(left.Value, right.Value) < 0;
+ ///
+ /// Compare to another Length object
+ ///
+ ///
+ /// 0 if equal
+ [Pure] public readonly int CompareTo(Length other) => Equals(Value, other.Value) ? 0 : Value.CompareTo(other.Value);
- ///
- /// Greater than operator to compare two Length objects
- ///
- /// left value
- /// right value
- /// true if left is greater than right
- [Pure] public static bool operator >(Length left, Length right) => Comparer.Default.Compare(left.Value, right.Value) > 0;
+ ///
+ /// Less than operator to compare two Length objects
+ ///
+ /// left value
+ /// right value
+ /// true if left is less than right
+ [Pure] public static bool operator <(Length left, Length right) => Comparer.Default.Compare(left.Value, right.Value) < 0;
- ///
- /// Less than or equal operator to compare two Length objects
- ///
- /// left value
- /// right value
- /// true if left is less than or equal to right
- [Pure] public static bool operator <=(Length left, Length right) => Comparer.Default.Compare(left.Value, right.Value) <= 0;
+ ///
+ /// Greater than operator to compare two Length objects
+ ///
+ /// left value
+ /// right value
+ /// true if left is greater than right
+ [Pure] public static bool operator >(Length left, Length right) => Comparer.Default.Compare(left.Value, right.Value) > 0;
- ///
- /// Greater than or equal operator to compare two Length objects
- ///
- /// left value
- /// right value
- /// true if left is greater than or equal to right
- [Pure] public static bool operator >=(Length left, Length right) => Comparer.Default.Compare(left.Value, right.Value) >= 0;
+ ///
+ /// Less than or equal operator to compare two Length objects
+ ///
+ /// left value
+ /// right value
+ /// true if left is less than or equal to right
+ [Pure] public static bool operator <=(Length left, Length right) => Comparer.Default.Compare(left.Value, right.Value) <= 0;
- // Math
- ///
- /// Addition operator to add two Length objects
- ///
- /// left value
- /// right value
- /// A new Length object with a value of left + right
- [Pure] public static Length operator +(Length left, Length right) => new (left.Value + right.Value);
+ ///
+ /// Greater than or equal operator to compare two Length objects
+ ///
+ /// left value
+ /// right value
+ /// true if left is greater than or equal to right
+ [Pure] public static bool operator >=(Length left, Length right) => Comparer.Default.Compare(left.Value, right.Value) >= 0;
- ///
- /// Subtraction operator to subtract two Length objects
- ///
- /// left value
- /// right value
- /// A new Length object with a value of left - right
- [Pure] public static Length operator -(Length left, Length right) => new (left.Value - right.Value);
+ // Math
+ ///
+ /// Addition operator to add two Length objects
+ ///
+ /// left value
+ /// right value
+ /// A new Length object with a value of left + right
+ [Pure] public static Length operator +(Length left, Length right) => new(left.Value + right.Value);
- ///
- /// Multiplication operator to multiply by a double
- ///
- /// object to multiply
- /// operand to multiply object
- /// A new Length object with a value of value multiplied by the operand
- [Pure] public static Length operator *(Length value, double operand) => new (value.Value * operand);
+ ///
+ /// Subtraction operator to subtract two Length objects
+ ///
+ /// left value
+ /// right value
+ /// A new Length object with a value of left - right
+ [Pure] public static Length operator -(Length left, Length right) => new(left.Value - right.Value);
- ///
- /// Division operator to divide by a double
- ///
- /// object to be divided
- /// operand to divide object
- /// A new Length object with a value of value divided by the operand
- [Pure] public static Length operator /(Length value, double operand) => new (value.Value / operand);
+ ///
+ /// Multiplication operator to multiply by a double
+ ///
+ /// object to multiply
+ /// operand to multiply object
+ /// A new Length object with a value of value multiplied by the operand
+ [Pure] public static Length operator *(Length value, double operand) => new(value.Value * operand);
- ///
- /// Returns the absolute value of the
- ///
- ///
- [Pure] public Length Abs() { return new Length(Math.Abs(this.Value)); }
+ ///
+ /// Division operator to divide by a double
+ ///
+ /// object to be divided
+ /// operand to divide object
+ /// A new Length object with a value of value divided by the operand
+ [Pure] public static Length operator /(Length value, double operand) => new(value.Value / operand);
- ///
- /// Get a string representation of the object
- ///
- /// A string representing the object
- [Pure] public override string ToString() => Value.ToString();
+ ///
+ /// Returns the absolute value of the
+ ///
+ ///
+ [Pure] public readonly Length Abs() { return new Length(Math.Abs(this.Value)); }
- ///
- /// Get a string representation of the object
- ///
- /// format
- /// format provider
- /// A string representing the object
- [Pure] public string ToString(string format, IFormatProvider formatProvider) => Value.ToString(format, formatProvider);
+ ///
+ /// Get a string representation of the object
+ ///
+ /// A string representing the object
+ [Pure] public override readonly string ToString() => Value.ToString();
- // IComparable
- ///
- /// Compare to another Length object
- ///
- /// The other Length cast to object
- /// 0 if equal
- [Pure] public int CompareTo(object obj) => Value.CompareTo(obj);
+ ///
+ /// Get a string representation of the object
+ ///
+ /// format
+ /// format provider
+ /// A string representing the object
+ [Pure] public readonly string ToString(string format, IFormatProvider formatProvider) => Value.ToString(format, formatProvider);
- ///
- /// Get type code of object
- ///
- /// The TypeCode
- [Pure] public TypeCode GetTypeCode() => Value.GetTypeCode();
+ // IComparable
+ ///
+ /// Compare to another Length object
+ ///
+ /// The other Length cast to object
+ /// 0 if equal
+ [Pure] public readonly int CompareTo(object obj) => Value.CompareTo(obj);
- ///
- /// Convert to boolean
- ///
- /// format provider
- /// bool representation of the object
- [Pure] public bool ToBoolean(IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
+ ///
+ /// Get type code of object
+ ///
+ /// The TypeCode
+ [Pure] public readonly TypeCode GetTypeCode() => Value.GetTypeCode();
- ///
- /// Convert to byte
- ///
- /// format provider
- /// byte representation of the object
- [Pure] public byte ToByte(IFormatProvider provider) => ((IConvertible)Value).ToByte(provider);
+ ///
+ /// Convert to boolean
+ ///
+ /// format provider
+ /// bool representation of the object
+ [Pure] public readonly bool ToBoolean(IFormatProvider provider) => ((IConvertible)Value).ToBoolean(provider);
- ///
- /// Convert to char
- ///
- /// format provider
- /// char representation of the object
- [Pure] public char ToChar(IFormatProvider provider) => ((IConvertible)Value).ToChar(provider);
+ ///
+ /// Convert to byte
+ ///
+ /// format provider
+ /// byte representation of the object
+ [Pure] public readonly byte ToByte(IFormatProvider provider) => ((IConvertible)Value).ToByte(provider);
- ///
- /// Convert to DateTime
- ///
- /// format provider
- /// DateTime representation of the object
- [Pure] public DateTime ToDateTime(IFormatProvider provider) => ((IConvertible)Value).ToDateTime(provider);
+ ///
+ /// Convert to char
+ ///
+ /// format provider
+ /// char representation of the object
+ [Pure] public readonly char ToChar(IFormatProvider provider) => ((IConvertible)Value).ToChar(provider);
- ///
- /// Convert to Decimal
- ///
- /// format provider
- /// Decimal representation of the object
- [Pure] public decimal ToDecimal(IFormatProvider provider) => ((IConvertible)Value).ToDecimal(provider);
+ ///
+ /// Convert to DateTime
+ ///
+ /// format provider
+ /// DateTime representation of the object
+ [Pure] public readonly DateTime ToDateTime(IFormatProvider provider) => ((IConvertible)Value).ToDateTime(provider);
- ///
- /// Convert to double
- ///
- /// format provider
- /// double representation of the object
- [Pure] public double ToDouble(IFormatProvider provider) => Value;
+ ///
+ /// Convert to Decimal
+ ///
+ /// format provider
+ /// Decimal representation of the object
+ [Pure] public readonly decimal ToDecimal(IFormatProvider provider) => ((IConvertible)Value).ToDecimal(provider);
- ///
- /// Convert to in16
- ///
- /// format provider
- /// int16 representation of the object
- [Pure] public short ToInt16(IFormatProvider provider) => ((IConvertible)Value).ToInt16(provider);
+ ///
+ /// Convert to double
+ ///
+ /// format provider
+ /// double representation of the object
+ [Pure] public readonly double ToDouble(IFormatProvider provider) => Value;
- ///
- /// Convert to int32
- ///
- /// format provider
- /// int32 representation of the object
- [Pure] public int ToInt32(IFormatProvider provider) => ((IConvertible)Value).ToInt32(provider);
+ ///
+ /// Convert to in16
+ ///
+ /// format provider
+ /// int16 representation of the object
+ [Pure] public readonly short ToInt16(IFormatProvider provider) => ((IConvertible)Value).ToInt16(provider);
- ///
- /// Convert to int64
- ///
- /// format provider
- /// int64 representation of the object
- [Pure] public long ToInt64(IFormatProvider provider) => ((IConvertible)Value).ToInt64(provider);
+ ///
+ /// Convert to int32
+ ///
+ /// format provider
+ /// int32 representation of the object
+ [Pure] public readonly int ToInt32(IFormatProvider provider) => ((IConvertible)Value).ToInt32(provider);
- ///
- /// Convert to sbyte
- ///
- /// format provider
- /// sbyte representation of the object
- [Pure] public sbyte ToSByte(IFormatProvider provider) => ((IConvertible)Value).ToSByte(provider);
+ ///
+ /// Convert to int64
+ ///
+ /// format provider
+ /// int64 representation of the object
+ [Pure] public readonly long ToInt64(IFormatProvider provider) => ((IConvertible)Value).ToInt64(provider);
- ///
- /// Convert to float
- ///
- /// format provider
- /// float representation of the object
- [Pure] public float ToSingle(IFormatProvider provider) => ((IConvertible)Value).ToSingle(provider);
+ ///
+ /// Convert to sbyte
+ ///
+ /// format provider
+ /// sbyte representation of the object
+ [Pure] public readonly sbyte ToSByte(IFormatProvider provider) => ((IConvertible)Value).ToSByte(provider);
- ///
- /// Convert to string
- ///
- /// format provider
- /// string representation of the object
- [Pure] public string ToString(IFormatProvider provider) => Value.ToString(provider);
+ ///
+ /// Convert to float
+ ///
+ /// format provider
+ /// float representation of the object
+ [Pure] public readonly float ToSingle(IFormatProvider provider) => ((IConvertible)Value).ToSingle(provider);
- ///
- /// Convert to type
- ///
- /// type to covert to
- /// format provider
- /// type representation of the object
- [Pure] public object ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)Value).ToType(conversionType, provider);
+ ///
+ /// Convert to string
+ ///
+ /// format provider
+ /// string representation of the object
+ [Pure] public readonly string ToString(IFormatProvider provider) => Value.ToString(provider);
- ///
- /// Convert to uint16
- ///
- /// format provider
- /// uint16 representation of the object
- [Pure] public ushort ToUInt16(IFormatProvider provider) => ((IConvertible)Value).ToUInt16(provider);
+ ///
+ /// Convert to type
+ ///
+ /// type to covert to
+ /// format provider
+ /// type representation of the object
+ [Pure] public readonly object ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)Value).ToType(conversionType, provider);
- ///
- /// Convert to uint32
- ///
- /// format provider
- /// uint32 representation of the object
- [Pure] public uint ToUInt32(IFormatProvider provider) => ((IConvertible)Value).ToUInt32(provider);
+ ///
+ /// Convert to uint16
+ ///
+ /// format provider
+ /// uint16 representation of the object
+ [Pure] public readonly ushort ToUInt16(IFormatProvider provider) => ((IConvertible)Value).ToUInt16(provider);
- ///
- /// Convert to uint64
- ///
- /// format provider
- /// uint64 representation of the object
- [Pure] public ulong ToUInt64(IFormatProvider provider) => ((IConvertible)Value).ToUInt64(provider);
+ ///
+ /// Convert to uint32
+ ///
+ /// format provider
+ /// uint32 representation of the object
+ [Pure] public readonly uint ToUInt32(IFormatProvider provider) => ((IConvertible)Value).ToUInt32(provider);
- ///
- /// Compare the default value to a double
- ///
- /// value to compare
- /// 0 if equal
- [Pure] public int CompareTo(double? other)
- {
- return (other is null) ? -1 : (Value).CompareTo(other.Value);
- }
+ ///
+ /// Convert to uint64
+ ///
+ /// format provider
+ /// uint64 representation of the object
+ [Pure] public readonly ulong ToUInt64(IFormatProvider provider) => ((IConvertible)Value).ToUInt64(provider);
- ///
- /// Compare the default value to a double
- ///
- /// value to compare
- /// 0 if equal
- [Pure] public bool Equals(double? other) => Value.Equals(other);
+ ///
+ /// Compare the default value to a double
+ ///
+ /// value to compare
+ /// 0 if equal
+ [Pure]
+ public readonly int CompareTo(double? other)
+ {
+ return (other is null) ? -1 : (Value).CompareTo(other.Value);
+ }
- ///
- /// Compare the default value to a double
- ///
- /// value to compare
- /// 0 if equal
- [Pure] public bool Equals(double other) => Value.Equals(other);
+ ///
+ /// Compare the default value to a double
+ ///
+ /// value to compare
+ /// 0 if equal
+ [Pure] public readonly bool Equals(double? other) => Value.Equals(other);
- ///
- /// Compare the default value to a double
- ///
- /// value to compare
- /// 0 if equal
- [Pure] public int CompareTo(double other) => Value.CompareTo(other);
- }
+ ///
+ /// Compare the default value to a double
+ ///
+ /// value to compare
+ /// 0 if equal
+ [Pure] public readonly bool Equals(double other) => Value.Equals(other);
+
+ ///
+ /// Compare the default value to a double
+ ///
+ /// value to compare
+ /// 0 if equal
+ [Pure] public readonly int CompareTo(double other) => Value.CompareTo(other);
}
\ No newline at end of file