With this extension we can parse strings directly to a numeric type
static bool Fail<T>(this object _, out T item) where T : struct
{
item = default;
return false;
}
static bool Pass<T>(this object obj, out T item) where T : struct
{
Type conversionType = typeof(T);
item = (T)Convert.ChangeType(obj, conversionType);
return true;
}
const string System_Int16 = "System.Int16";
const string System_UInt16 = "System.UInt16";
const string System_Int32 = "System.Int32";
const string System_Int64 = "System.Int64";
const string System_UInt32 = "System.UInt32";
const string System_Single = "System.Single";
const string System_Double = "System.Double";
const string System_UInt64 = "System.UInt64";
const string System_Byte = "System.Byte";
const string System_Decimal = "System.Decimal";
const string System_SByte = "System.SByte";
const string System_Numerics_BigInteger = "System.Numerics.BigInteger";
public static bool TryParse<T>(this string value, out T item) where T : struct
{
var conversionType = typeof(T);
var floatType = typeof(float);
var doubleType = typeof(double);
var decimalType = typeof(decimal);
if(conversionType != floatType && conversionType != doubleType
&& conversionType != decimalType && value.Contains('.'))
{
//we're not converting to float, double or decimal
//there's no rounding, we just drop everything from the "."
value = value.Remove(value.LastIndexOf('.'));
}
return conversionType.FullName switch
{
System_Int16 => short.TryParse(value, out var result) ?
result.Pass(out item) : value.Fail(out item),
System_UInt16 => ushort.TryParse(value, out var result) ?
result.Pass(out item) : value.Fail(out item),
System_Decimal => decimal.TryParse(value, out var result) ?
result.Pass(out item) : value.Fail(out item),
System_Int32 => int.TryParse(value, out var result) ?
result.Pass(out item) : value.Fail(out item),
System_Int64 => long.TryParse(value, out var result) ?
result.Pass(out item) : value.Fail(out item),
System_UInt64 => ulong.TryParse(value, out var result) ?
result.Pass(out item) : value.Fail(out item),
System_UInt32 => uint.TryParse(value, out var result) ?
result.Pass(out item) : value.Fail(out item),
System_Single => float.TryParse(value, out var result) ?
result.Pass(out item) : value.Fail(out item),
System_Double => double.TryParse(value, out var result) ?
result.Pass(out item) : value.Fail(out item),
System_Byte => byte.TryParse(value, out var result) ?
result.Pass(out item) : value.Fail(out item),
System_SByte => sbyte.TryParse(value, out var result) ?
result.Pass(out item) : value.Fail(out item),
System_Numerics_BigInteger => BigInteger.TryParse(value, out var result) ?
result.Pass(out item) : value.Fail(out item),
_ => conversionType.Fail(out item)
} ;
}