我正在尝试编写一个扩展方法,给定一个值,它将返回
DBNull.Value
value
的类型是的,这不是最明确的解释,也许某些代码会使我想要完成的事情显而易见。
public static T GetValueOrDefault<T>(this object value) {
if (value == DBNull.Value)
return default(T);
else
return (T)value;
}
只要value
的盒装类型与T
相同,此方法就可以正常工作。
当类型不同时,真正有趣的是,例如盒装值为byte
而T
为int
。
是否有一种优雅的方式使这项工作?
手动进行一些类型检查以从例如object
到byte
然后从byte
到T
,当然不会有用。
修改
建议的解决方案也应该与枚举一起使用,而不仅仅是“标准”类型。
答案 0 :(得分:4)
使用与数据库值完全匹配的类型参数调用您的方法,然后将其转换为您实际需要的值,例如。
int result = (int) row["NullableByteColumn"].GetValueOrDefault<byte>();
我认为这是合理的,因为代码清楚地区分了两个不同的概念:
如果所需的数据类型从int
进一步删除并需要更复杂的翻译,则责任分离变得更加重要,例如:枚举,字符串或偏离日期的日期。
答案 1 :(得分:2)
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));
}
}
答案 2 :(得分:0)
这对我有用:
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;
}
}
}