/// <summary> /// Infer from the input string what type it is, and return the field as that type /// (int, long, decimal, double, bool or string) /// </summary> /// <param name="input">the input sting</param> /// <returns>the value cast to the type it could be parsed into</returns> public static object CastToInferredType(this string input) { var target = input; // we infer hex numbers to be signed; size in bytes determines which return value to be used // (byte, short, int, long) if (NumericFunctions.TryParseHex(input, true, out var hexValue)) { target = hexValue.ToString(); } if (int.TryParse(target, out var intValue)) { return(intValue); } if (long.TryParse(target, out var longValue)) { return(longValue); } if (decimal.TryParse(target, out var decimalValue)) { return(decimalValue); } if (double.TryParse(target, out var doubleValue)) { return(doubleValue); } if (bool.TryParse(target, out var boolValue)) { return(boolValue); } return(input); }
private static object ChangeType(object value, Type targetType) { var source = value; // if we want a numeric result and we have a hex value, convert the hex to long first. if (targetType.IsNumeric() && NumericFunctions.TryParseHex(value?.ToString(), targetType.IsSigned(), out var hexValue)) { source = hexValue; } try { return(Convert.ChangeType(source, targetType, InvariantCulture)); } catch (Exception e) when(e is FormatException || e is InvalidCastException) { try { return(Convert.ChangeType(source, targetType, CurrentUICulture)); } catch (Exception fe) when(fe is FormatException || fe is InvalidCastException) { throw new FormatException(Invariant($"Could not convert '{value}' to {targetType.Name}"), fe); } } }
/// <summary> /// Get the type that the input value can be parsed into (int, long, double, bool, string) /// </summary> /// <param name="value">the value to be examined</param> /// <returns>The type it was successfully parsed into</returns> public static Type InferType(this object value) { var stringValue = value?.ToString(); // we infer hex numbers to be signed, see CastToInferredType if (NumericFunctions.TryParseHex(stringValue, true, out var hexValue)) { stringValue = hexValue.ToString(); } if (int.TryParse(stringValue, NumberStyles.Integer, InvariantCulture, out _)) { return(typeof(int)); } if (long.TryParse(stringValue, NumberStyles.Integer, InvariantCulture, out _)) { return(typeof(long)); } if (double.TryParse(stringValue, NumberStyles.Any, InvariantCulture, out _)) { return(typeof(double)); } if (double.TryParse(stringValue, NumberStyles.Any, CurrentUICulture, out _)) { return(typeof(double)); } return(bool.TryParse(stringValue, out _) ? typeof(bool) : typeof(string)); }