To exclude the possibility that you are getting an object that can't be converted to a long, test with another function that uses Int64.TryGetValue, and break on error to examine the data.
I would rather use hard-coded Type specific conversion methods, which throw useful errors. Use of 'ChangeType is expensive. Here's an example of the type of Extension method I use:
public static class ConversionExtensions
{
public static Int32 ToInt(this string str, bool doThrowOnError = true, int defaultValue = Int32.MinValue)
{
int i;
if (Int32.TryParse(str, out i))
{
return i;
}
if (doThrowOnError)
{
throw new ArgumentException($"{str} is not convertible to Int32");
}
return defaultValue;
}
}
If you want to "go generic," then try something like this:
using System.ComponentModel;
public T2 DbTypeConverter<T1,T2>(T1 value)
{
if (value == null || Convert.IsDBNull(value))
{
return default(T2);
}
TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(T2));
if (typeConverter.CanConvertFrom(typeof(T1)))
{
try
{
return (T2) Convert.ChangeType(value, typeof(T2));
}
catch (Exception ex)
{
switch (ex.GetType().Name)
{
case "InvalidFormatException":
break;
case "InvalidCastException":
break;
case "FormatException":
break;
case "OverflowException":
break;
case "ArgumentException":
break;
}
}
}
return default(T2);
}
Good info on what you can, and can't, do with TypeConverter: [
^]