Invalid cast from 'System.Double' to 'System.Nullable`

neildt picture neildt · Nov 6, 2013 · Viewed 10.3k times · Source

I've the following function which was based on this inital Generic function to handle DataType Conversion

public static T ConvertFromDB<T>(object value)
{
  return value == DBNull.Value ? default(T) : (T)Convert.ChangeType(value, typeof(T));
}

It works fine. However when passing in a double like 0 I get the following exception;

Invalid cast from 'System.Double' to 'System.Nullable`1[[System.Double, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'.

I've tried casting as a float but still the same. Any ideas why this is happening ?

Answer

Marc Gravell picture Marc Gravell · Nov 6, 2013

Simply : that isn't a supported usage of Convert.ChangeType. You need to give it the non-nullable form, i.e. double. You could use Nullable.GetUnderlyingType:

return value == DBNull.Value ? default(T) : (T)Convert.ChangeType(value,
      Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T));

but this will have overhead; personally, I suspect it might be easier to use a Nullable<T> specific method:

public static T? GetValue<T>(object value) where T : struct
{
    if(value == null || value is DBNull) return null;
    if(value is T) return (T)value;
    return (T)Convert.ChangeType(value, typeof(T));
}

Or even better yet: use a an ORM or micro-ORM, so you don't need to do this stuff (also: they'll do a better job of it, by thinking about the type conversions during the meta-programming code, rather than the per-value execution code).