/// <summary> /// Convert between any two quantity units by their names, such as converting a "Length" of N "Meter" to "Centimeter". /// This is particularly useful for creating things like a generated unit conversion UI, /// where you list some selectors: /// a) Quantity: Length, Mass, Force etc. /// b) From unit: Meter, Centimeter etc if Length is selected /// c) To unit: Meter, Centimeter etc if Length is selected /// </summary> /// <param name="fromValue"> /// Input value, which together with <paramref name="fromUnit" /> represents the quantity to /// convert from. /// </param> /// <param name="quantityName"> /// Name of quantity, such as "Length" and "Mass". <see cref="QuantityType" /> for all /// values. /// </param> /// <param name="fromUnit"> /// Name of unit, such as "Meter" or "Centimeter" if "Length" was passed as /// <paramref name="quantityName" />. /// </param> /// <param name="toUnit"> /// Name of unit, such as "Meter" or "Centimeter" if "Length" was passed as /// <paramref name="quantityName" />. /// </param> /// <example>double centimeters = ConvertByName(5, "Length", "Meter", "Centimeter"); // 500</example> /// <returns>Output value as the result of converting to <paramref name="toUnit" />.</returns> /// <exception cref="QuantityNotFoundException">No quantities were found that match <paramref name="quantityName" />.</exception> /// <exception cref="UnitNotFoundException">No units match the abbreviation.</exception> /// <exception cref="AmbiguousUnitParseException">More than one unit matches the abbrevation.</exception> public static double ConvertByName(FromValue fromValue, string quantityName, string fromUnit, string toUnit) { if (!TryGetQuantityType(quantityName, out var quantityType)) { throw new QuantityNotFoundException($"The given quantity name was not found: {quantityName}"); } if (!TryGetUnitType(quantityName, out var unitType)) { throw new UnitNotFoundException($"The unit type for the given quantity was not found: {quantityName}"); } if (!TryParseUnit(unitType, fromUnit, out var fromUnitValue)) // ex: LengthUnit.Meter { var e = new UnitNotFoundException($"Unit not found [{fromUnit}]."); e.Data["unitName"] = fromUnit; throw e; } if (!TryParseUnit(unitType, toUnit, out var toUnitValue)) // ex: LengthUnit.Centimeter { var e = new UnitNotFoundException($"Unit not found [{toUnit}]."); e.Data["unitName"] = toUnit; throw e; } var fromMethod = GetStaticFromMethod(quantityType, unitType); // ex: UnitsNet.Length.From(double inputValue, LengthUnit inputUnit) var fromResult = fromMethod.Invoke(null, new[] { fromValue, fromUnitValue }); // ex: Length quantity = UnitsNet.Length.From(5, LengthUnit.Meter) var asMethod = GetAsMethod(quantityType, unitType); // ex: quantity.As(LengthUnit outputUnit) var asResult = asMethod.Invoke(fromResult, new[] { toUnitValue }); // ex: double outputValue = quantity.As(LengthUnit.Centimeter) return((double)asResult); }
/// <summary> /// Parse a unit by the unit enum type <paramref name="unitType" /> and a unit enum value <paramref name="unitName" />> /// </summary> /// <param name="unitType">Unit type, such as <see cref="LengthUnit" />.</param> /// <param name="unitName">Unit name, such as "Meter" corresponding to <see cref="LengthUnit.Meter" />.</param> /// <returns>Unit enum value, such as <see cref="LengthUnit.Meter" /> boxed as an object.</returns> /// <exception cref="UnitNotFoundException">No unit values match the <paramref name="unitName" />.</exception> private static object ParseUnit(Type unitType, string unitName) { object unitValue; // ex: LengthUnit.Meter try { unitValue = Enum.Parse(unitType, unitName); } catch (Exception e) { var e2 = new UnitNotFoundException($"Unit not found [{unitName}].", e); e2.Data["unitName"] = unitName; throw e2; } return(unitValue); }
/// <summary> /// Convert between any two quantity units by their names, such as converting a "Length" of N "Meter" to "Centimeter". /// This is particularly useful for creating things like a generated unit conversion UI, /// where you list some selectors: /// a) Quantity: Length, Mass, Force etc. /// b) From unit: Meter, Centimeter etc if Length is selected /// c) To unit: Meter, Centimeter etc if Length is selected /// </summary> /// <param name="fromValue"> /// Input value, which together with <paramref name="fromUnit" /> represents the quantity to /// convert from. /// </param> /// <param name="quantityName"> /// Name of quantity, such as "Length" and "Mass". <see cref="QuantityType" /> for all /// values. /// </param> /// <param name="fromUnit"> /// Name of unit, such as "Meter" or "Centimeter" if "Length" was passed as /// <paramref name="quantityName" />. /// </param> /// <param name="toUnit"> /// Name of unit, such as "Meter" or "Centimeter" if "Length" was passed as /// <paramref name="quantityName" />. /// </param> /// <example>double centimeters = ConvertByName(5, "Length", "Meter", "Centimeter"); // 500</example> /// <returns>Output value as the result of converting to <paramref name="toUnit" />.</returns> /// <exception cref="QuantityNotFoundException">No quantities were found that match <paramref name="quantityName" />.</exception> /// <exception cref="UnitNotFoundException">No units match the abbreviation.</exception> /// <exception cref="AmbiguousUnitParseException">More than one unit matches the abbreviation.</exception> public static double ConvertByName(QuantityValue fromValue, string quantityName, string fromUnit, string toUnit) { if (!TryGetUnitType(quantityName, out Type unitType)) { throw new UnitNotFoundException($"The unit type for the given quantity was not found: {quantityName}"); } if (!TryParseUnit(unitType, fromUnit, out Enum fromUnitValue)) // ex: LengthUnit.Meter { var e = new UnitNotFoundException($"Unit not found [{fromUnit}]."); e.Data["unitName"] = fromUnit; throw e; } if (!TryParseUnit(unitType, toUnit, out Enum toUnitValue)) // ex: LengthUnit.Centimeter { var e = new UnitNotFoundException($"Unit not found [{toUnit}]."); e.Data["unitName"] = toUnit; throw e; } return(Convert(fromValue, fromUnitValue, toUnitValue)); }