I'm trying to write an extension method that, given a value, will return
DBNull.Value
value's typeYeah, that's not the clearest explanation, maybe some code will make what I'm trying to accomplish obvious.
public static T GetValueOrDefault<T>(this object value) {
if (value == DBNull.Value)
return default(T);
else
return (T)value;
}
As long as value's boxed type is the same as T, this method works correctly.
The real fun kicks in when the types are different, for instance the boxed value is byte and T is int.
Is there an elegant way to make this work?
Doing some typechecking manually to first cast from e.g. object to byte and then from byte to T, of course, won't work.
Edit
The proposed solution should work with enums too, not only with "standard" types.
Call your method with a type argument that exactly matches the database value, then cast it to what you actually want, e.g.
int result = (int) row["NullableByteColumn"].GetValueOrDefault<byte>();
I think this is reasonable because the code clearly separates the two different concepts that are at work here:
This separation of responsibility becomes more important if the required data type is something further removed from int and requires more complex translation, e.g. an enum, a string, or a day offset from a date.
public static T GetValueOrDefault<T>(this object value) {
if (value == DBNull.Value) {
return default(T);
}
else {
if (typeof(T).IsEnum) value = Enum.ToObject(typeof(T), Convert.ToInt64(value));
return (T)Convert.ChangeType(value, typeof(T));
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With