diff --git a/UnitsNet/UnitConverter.cs b/UnitsNet/UnitConverter.cs
index 654f44f37a..f4e25b8073 100644
--- a/UnitsNet/UnitConverter.cs
+++ b/UnitsNet/UnitConverter.cs
@@ -69,23 +69,38 @@ public static class UnitConverter
///
/// double centimeters = ConvertByName(5, "Length", "Meter", "Centimeter"); // 500
/// Output value as the result of converting to .
+ /// No quantities were found that match .
/// No units match the abbreviation.
/// More than one unit matches the abbrevation.
public static double ConvertByName(FromValue fromValue, string quantityName, string fromUnit, string toUnit)
{
- Type quantityType = GetQuantityType(quantityName);
- Type unitType = GetUnitType(quantityName);
+ if(!TryGetQuantityType(quantityName, out var quantityType))
+ throw new QuantityNotFoundException($"The given quantity name was not found: {quantityName}");
- object fromUnitValue = ParseUnit(unitType, fromUnit); // ex: LengthUnit.Meter
- object toUnitValue = ParseUnit(unitType, toUnit); // ex: LengthUnit.Centimeter
+ if(!TryGetUnitType(quantityName, out var unitType))
+ throw new UnitNotFoundException($"The unit type for the given quantity was not found: {quantityName}");
- MethodInfo fromMethod = GetStaticFromMethod(quantityType, unitType); // ex: UnitsNet.Length.From(double inputValue, LengthUnit inputUnit)
- object fromResult = fromMethod.Invoke(null, new[] {fromValue, fromUnitValue}); // ex: Length quantity = UnitsNet.Length.From(5, LengthUnit.Meter)
+ 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)
- MethodInfo asMethod = GetAsMethod(quantityType, unitType); // ex: quantity.As(LengthUnit outputUnit)
- object asResult = asMethod.Invoke(fromResult, new[] {toUnitValue}); // ex: double outputValue = quantity.As(LengthUnit.Centimeter)
+ 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;
+ return (double)asResult;
}
///
@@ -117,21 +132,28 @@ public static double ConvertByName(FromValue fromValue, string quantityName, str
/// True if conversion was successful.
public static bool TryConvertByName(FromValue inputValue, string quantityName, string fromUnit, string toUnit, out double result)
{
- try
- {
- // Re-implement this to avoid exceptions where possible, as Try methods are generally recommended for performance and this is cheating.
- // https://msdn.microsoft.com/en-us/library/ms229009(v=vs.100).aspx
- //
- // Implement Try-methods without try-catch #504
- // https://github.com/angularsen/UnitsNet/issues/504
- result = ConvertByName(inputValue, quantityName, fromUnit, toUnit);
- return true;
- }
- catch
- {
- result = 0;
+ result = 0d;
+
+ if(!TryGetQuantityType(quantityName, out var quantityType))
return false;
- }
+
+ if(!TryGetUnitType(quantityName, out var unitType))
+ return false;
+
+ if(!TryParseUnit(unitType, fromUnit, out var fromUnitValue)) // ex: LengthUnit.Meter
+ return false;
+
+ if(!TryParseUnit(unitType, toUnit, out var toUnitValue)) // ex: LengthUnit.Centimeter
+ return false;
+
+ var fromMethod = GetStaticFromMethod(quantityType, unitType); // ex: UnitsNet.Length.From(double inputValue, LengthUnit inputUnit)
+ var fromResult = fromMethod.Invoke(null, new[] {inputValue, 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)
+
+ result = (double)asResult;
+ return true;
}
///
@@ -199,20 +221,23 @@ public static double ConvertByAbbreviation(FromValue fromValue, string quantityN
/// More than one unit matches the abbrevation.
public static double ConvertByAbbreviation(FromValue fromValue, string quantityName, string fromUnitAbbrev, string toUnitAbbrev, string culture)
{
- Type quantityType = GetQuantityType(quantityName);
- Type unitType = GetUnitType(quantityName);
+ 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}");
- UnitSystem unitSystem = UnitSystem.GetCached(culture);
- object fromUnitValue = unitSystem.Parse(fromUnitAbbrev, unitType); // ex: ("m", LengthUnit) => LengthUnit.Meter
- object toUnitValue = unitSystem.Parse(toUnitAbbrev, unitType); // ex:("cm", LengthUnit) => LengthUnit.Centimeter
+ var unitSystem = UnitSystem.GetCached(culture);
+ var fromUnitValue = unitSystem.Parse(fromUnitAbbrev, unitType); // ex: ("m", LengthUnit) => LengthUnit.Meter
+ var toUnitValue = unitSystem.Parse(toUnitAbbrev, unitType); // ex:("cm", LengthUnit) => LengthUnit.Centimeter
- MethodInfo fromMethod = GetStaticFromMethod(quantityType, unitType); // ex: UnitsNet.Length.From(double inputValue, LengthUnit inputUnit)
- object fromResult = fromMethod.Invoke(null, new[] {fromValue, fromUnitValue}); // ex: Length quantity = UnitsNet.Length.From(5, LengthUnit.Meter)
+ 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)
- MethodInfo asMethod = GetAsMethod(quantityType, unitType); // ex: quantity.As(LengthUnit outputUnit)
- object asResult = asMethod.Invoke(fromResult, new[] {toUnitValue}); // ex: double outputValue = quantity.As(LengthUnit.Centimeter)
+ 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;
+ return (double)asResult;
}
///
@@ -278,23 +303,31 @@ public static bool TryConvertByAbbreviation(FromValue fromValue, string quantity
public static bool TryConvertByAbbreviation(FromValue fromValue, string quantityName, string fromUnitAbbrev, string toUnitAbbrev, out double result,
string culture)
{
- try
- {
- // Re-implement this to avoid exceptions where possible, as Try methods are generally recommended for performance and this is cheating.
- // https://msdn.microsoft.com/en-us/library/ms229009(v=vs.100).aspx
- //
- // Implement Try-methods without try-catch #504
- // https://github.com/angularsen/UnitsNet/issues/504
- result = ConvertByAbbreviation(fromValue, quantityName, fromUnitAbbrev, toUnitAbbrev, culture);
- return true;
- }
- catch
- {
- result = 0;
+ result = 0d;
+
+ if(!TryGetQuantityType(quantityName, out var quantityType))
return false;
- }
- }
+ if(!TryGetUnitType(quantityName, out var unitType))
+ return false;
+
+ var unitSystem = UnitSystem.GetCached(culture);
+
+ if(!unitSystem.TryParse(fromUnitAbbrev, unitType, out var fromUnitValue)) // ex: ("m", LengthUnit) => LengthUnit.Meter
+ return false;
+
+ if(!unitSystem.TryParse(toUnitAbbrev, unitType, out var toUnitValue)) // ex:("cm", LengthUnit) => LengthUnit.Centimeter
+ return false;
+
+ 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)
+
+ result = (double)asResult;
+ return true;
+ }
private static MethodInfo GetAsMethod(Type quantityType, Type unitType)
{
@@ -322,14 +355,14 @@ private static MethodInfo GetStaticFromMethod(Type quantityType, Type unitType)
private static bool HasParameterTypes(MethodInfo methodInfo, params Type[] expectedTypes)
{
- ParameterInfo[] parameters = methodInfo.GetParameters();
+ var parameters = methodInfo.GetParameters();
if (parameters.Length != expectedTypes.Length)
throw new ArgumentException($"The number of parameters {parameters.Length} did not match the number of types {expectedTypes.Length}.");
for (var i = 0; i < parameters.Length; i++)
{
- ParameterInfo p = parameters[i];
- Type t = expectedTypes[i];
+ var p = parameters[i];
+ var t = expectedTypes[i];
if (p.ParameterType != t)
return false;
}
@@ -343,40 +376,43 @@ private static bool HasParameterTypes(MethodInfo methodInfo, params Type[] expec
///
/// Unit type, such as .
/// Unit name, such as "Meter" corresponding to .
- /// Unit enum value, such as boxed as an object.
+ /// The return enum value, such as boxed as an object.
+ /// True if succeeded, otherwise false.
/// No unit values match the .
- private static object ParseUnit(Type unitType, string unitName)
+ private static bool TryParseUnit(Type unitType, string unitName, out object unitValue)
{
- 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;
+ unitValue = null;
+
+ if(!Enum.IsDefined(unitType, unitName))
+ return false;
+
+ unitValue = Enum.Parse(unitType, unitName);
+ if(unitValue == null)
+ return false;
+
+ return true;
}
- private static Type GetUnitType(string quantityName)
+ private static bool TryGetUnitType(string quantityName, out Type unitType)
{
string unitTypeName = $"{UnitTypeNamespace}.{quantityName}Unit";
- Type unitType = UnitsNetAssembly.GetType(unitTypeName); // ex: UnitsNet.Units.LengthUnit enum
- if (unitType == null)
- throw new UnitNotFoundException($"Unit type name not found: {unitTypeName}");
- return unitType;
+
+ unitType = UnitsNetAssembly.GetType(unitTypeName); // ex: UnitsNet.Units.LengthUnit enum
+ if(unitType == null)
+ return false;
+
+ return true;
}
- private static Type GetQuantityType(string quantityName)
+ private static bool TryGetQuantityType(string quantityName, out Type quantityType)
{
string quantityTypeName = $"{QuantityNamespace}.{quantityName}";
- Type quantityType = UnitsNetAssembly.GetType(quantityTypeName); // ex: UnitsNet.Length struct
- if (quantityType == null)
- throw new QuantityNotFoundException($"Quantity type name not found: {quantityTypeName}");
- return quantityType;
+
+ quantityType = UnitsNetAssembly.GetType(quantityTypeName); // ex: UnitsNet.Length struct
+ if(quantityType == null)
+ return false;
+
+ return true;
}
}
}