Example #1
0
 /// <summary>
 /// Converts this quantity from this <see cref="Unit"/> to another <see cref="MeasureUnit"/>.
 /// Must be called only if <see cref="CanConvertTo(MeasureUnit)"/> returned true otherwise an <see cref="ArgumentException"/>
 /// is thrown.
 /// </summary>
 /// <param name="u">The target unit of measure.</param>
 /// <returns>The quantity exporessed with the target unit.</returns>
 public Quantity ConvertTo(MeasureUnit u)
 {
     if (Unit == u)
     {
         return(this);
     }
     if (!CanConvertTo(u))
     {
         if (u.Context != Unit.Context)
         {
             throw new ArgumentException($"Can not convert between units in different contexts ('{Unit}' to '{u}').");
         }
         throw new ArgumentException($"Can not convert from '{Unit}' to '{u}'.");
     }
     if (Unit.Normalization == u.Normalization)
     {
         FullFactor ratio = Unit.NormalizationFactor.DivideBy(u.NormalizationFactor);
         return(new Quantity(Value * ratio.ToDouble(), u));
     }
     else
     {
         FullFactor ratio = Unit.NormalizationFactor.Multiply(u.NormalizationFactor);
         return(new Quantity(1 / (Value * ratio.ToDouble()), u));
     }
 }
 /// <summary>
 /// Defines an alias.
 /// The same alias can be registered multiple times but it has to exactly match the previously registered one.
 /// </summary>
 /// <param name="abbreviation">
 /// The unit of measure abbreviation.
 /// This is the key that is used. It must not be null or empty.
 /// </param>
 /// <param name="name">The full name. Must not be null or empty.</param>
 /// <param name="definitionFactor">
 /// The factor that applies to the <see cref="AliasMeasureUnit.Definition"/>.
 /// Must not be <see cref="FullFactor.Zero"/>.
 /// </param>
 /// <param name="definition">The definition. Can be any <see cref="MeasureUnit"/>.</param>
 /// <param name="autoStandardPrefix">
 /// Whether standard metric and/or binary prefixes can be applied to the unit.
 /// </param>
 /// <returns>The alias unit of measure.</returns>
 public AliasMeasureUnit DefineAlias(
     string abbreviation,
     string name,
     FullFactor definitionFactor,
     MeasureUnit definition,
     AutoStandardPrefix autoStandardPrefix = AutoStandardPrefix.None)
 {
     if (!IsValidNewAbbreviation(abbreviation, autoStandardPrefix))
     {
         throw new ArgumentException($"Invalid abbreviation {abbreviation}.", nameof(abbreviation));
     }
     if (String.IsNullOrWhiteSpace(name))
     {
         throw new ArgumentException("Must not be null or white space.", nameof(name));
     }
     if (definitionFactor.IsZero)
     {
         throw new ArgumentException("Must not be zero.", nameof(definitionFactor));
     }
     if (definition == null)
     {
         throw new ArgumentNullException(nameof(definition));
     }
     if (definition != MeasureUnit.None && definition.Context != this)
     {
         throw new Exception("Units' Context mismatch.");
     }
     return(RegisterAlias(abbreviation, name, definitionFactor, definition, autoStandardPrefix));
 }
 AliasMeasureUnit RegisterAlias(string a, string n, FullFactor f, MeasureUnit d, AutoStandardPrefix stdPrefix)
 {
     if (d == MeasureUnit.None)
     {
         if (f.Factor != 1.0)
         {
             throw new ArgumentException("Only exponential factor is allowed for dimensionless units.");
         }
         d = RegisterPrefixed(f.ExpFactor, MeasureStandardPrefix.None, MeasureUnit.None, false);
         f = FullFactor.Neutral;
     }
     return(Register(abbreviation: a,
                     name: n,
                     creator: () => new AliasMeasureUnit(this, a, n, f, d, stdPrefix),
                     checker: m =>
     {
         if (m.Definition.Normalization != d.Normalization)
         {
             ThrowArgumentException(m, $"new definition unit '{d}' is not compatible with '{m.Definition}'.");
         }
         if (m.NormalizationFactor != d.NormalizationFactor.Multiply(f))
         {
             ThrowArgumentException(m, $"new normalization factor '{f}' should be '{m.NormalizationFactor.DivideBy(d.NormalizationFactor)}'.");
         }
         CheckArgumentAutoStdPrefix(m, stdPrefix);
     }));
 }
 internal AliasMeasureUnit(
     MeasureContext ctx,
     string abbreviation, string name,
     FullFactor definitionFactor,
     MeasureUnit definition,
     AutoStandardPrefix stdPrefix)
     : base(ctx, abbreviation, name, stdPrefix, false)
 {
     DefinitionFactor = definitionFactor;
     Definition       = definition;
 }
 /// <summary>
 /// This ctor is used by <see cref="AtomicMeasureUnit"/>: it initializes a
 /// MeasureUnit bound to itself.
 /// </summary>
 /// <param name="ctx">The context.</param>
 /// <param name="abbreviation">The abbreviation.</param>
 /// <param name="name">The name.</param>
 /// <param name="isNormalized">True if this measure unit is the normalized one for its dimension.</param>
 private protected MeasureUnit(MeasureContext ctx, string abbreviation, string name, bool isNormalized)
 {
     _ctx         = ctx;
     Abbreviation = abbreviation;
     Name         = name;
     _units       = new[] { (ExponentMeasureUnit)this };
     if (isNormalized)
     {
         _normalizationFactor = FullFactor.Neutral;
         _normalization       = this;
         if (ctx == null)
         {
             _invert = this;
         }
     }
 }
Example #6
0
        /// <summary>
        /// Compares this quantity to another one.
        /// </summary>
        /// <param name="other">The other quantity to compare.</param>
        /// <returns></returns>
        public int CompareTo(Quantity other)
        {
            var tU = Unit;
            var oU = other.Unit;

            // Do the 2 units belong to the same (possibly null) context?
            if (tU.Context == oU.Context)
            {
                // First chexk our equality: we must do this first to ensure coherency.
                if (ToNormalizedString() == other.ToNormalizedString())
                {
                    return(0);
                }
                // Same unit, we compare the Values.
                if (tU == oU)
                {
                    return(Value.CompareTo(other.Value));
                }
                // Same normalized units, we convert this Value to the other unit before comparison.
                if (tU.Normalization == oU.Normalization)
                {
                    FullFactor ratio = tU.NormalizationFactor.DivideBy(oU.NormalizationFactor);
                    return((Value * ratio.ToDouble()).CompareTo(other.Value));
                }
                // Inverted normalized units, we convert this Value to the other unit before comparison.
                if (tU.Normalization == oU.Normalization.Invert())
                {
                    FullFactor ratio = tU.NormalizationFactor.Multiply(oU.NormalizationFactor);
                    return((1 / (Value * ratio.ToDouble())).CompareTo(other.Value));
                }
                // No possible conversion. How to compare kilograms and milliSievert?
                // Using their abbreviation (here kilogram will be "smaller" than milliSievert)
                return(tU.Abbreviation.CompareTo(oU.Abbreviation));
            }
            // Not in the same context.
            if (tU == MeasureUnit.None)
            {
                return(-1);
            }
            if (oU == MeasureUnit.None)
            {
                return(1);
            }
            return(tU.Context.Name.CompareTo(oU.Context.Name));
        }
 AliasMeasureUnit RegisterAlias(string a, string n, FullFactor f, MeasureUnit d, AutoStandardPrefix stdPrefix)
 {
     if (d == MeasureUnit.None)
     {
         if (f.Factor != 1.0)
         {
             throw new Exception("Only exponential factor is allowed for dimensionless units.");
         }
         d = RegisterPrefixed(f.ExpFactor, MeasureStandardPrefix.None, MeasureUnit.None, false);
         f = FullFactor.Neutral;
     }
     return(Register(abbreviation: a,
                     name: n,
                     creator: () => new AliasMeasureUnit(this, a, n, f, d, stdPrefix),
                     checker: m => m.Definition.Normalization == d.Normalization &&
                     m.NormalizationFactor == d.NormalizationFactor.Multiply(f) &&
                     m.AutoStandardPrefix == stdPrefix));
 }