Reputation: 8043
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.
Upvotes: 6
Views: 145
Reputation: 941635
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));
}
}
Upvotes: 2
Reputation: 31071
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.
Upvotes: 4
Reputation: 151604
This works for me:
class Program
{
static void Main(string[] args)
{
Byte myByte = 5;
object myObject = (object)myByte;
int myInt = myObject.GetValueOrDefault<Byte>();
Console.WriteLine(myInt); // 5
myObject = DBNull.Value;
myInt = myObject.GetValueOrDefault<Byte>();
Console.WriteLine(myInt); // 0
Console.ReadKey(true);
}
}
public static class ObjectExtension
{
public static T GetValueOrDefault<T>(this object value)
{
if (value == DBNull.Value)
{
return default(T);
}
else
{
return (T)value;
}
}
}
Upvotes: 0