在我的数据库中,v1字段是可以为空的字段。但如果值为null,我定义0(默认值)。
public decimal? v1 {
get {
return this._v1;
}
set {
this._v1 = value ?? 0M;
}
}
所以现在,v1不再是可空变量了。
但我不能这样做,
decimal v2 = v1;
错误消息说,无法隐式转换类型'decimal?'到'十进制'。
在这种情况下,我是否必须像这样转换为十进制?
decimal v2 = Convert.ToDecimal(v1);
这是非常讨厌的工作。而且代码看起来也很脏。
有谁知道更好的解决方案?请告诉我。
答案 0 :(得分:12)
不,您不必转换decimal?
,您可以访问Nullable
类型的基础值,例如。
decimal v2 = v1.Value;
为Nullable
类型分配默认值不会使其不可为空,它只是意味着它具有值。可空类型具有HasValue
属性,可帮助您确定此属性。
仅仅为了记录,我不建议将值默认为0
,考虑到它 确实为空,它可能更有意义让它默认为null
。如果您需要在应用中使用默认值,则可能需要使用GetValueOrDefault
方法,例如
decimal v2 = v1.GetValueOrDefault(0m);
答案 1 :(得分:4)
将decimal?
转换为decimal
但0
时值为null
的最简单方法,您可以这样做:
decimal? a = null;
decimal b = a.GetValueOrDefault(0m); // will contain 0 when null, otherwise the value
您也可以在没有参数的情况下调用GetValueOrDefault
,这将产生default(T)
,在Decimal的情况下为0,但我喜欢明确。
答案 2 :(得分:4)
我很好奇你为什么要将你的应用程序代码变量定义为可空,但如果它为null则将其设置为0。如果将空值从数据库传递到app变量,是否只是为了避免异常?如果你的应用程序并不是绝对需要可以为空的十进制变量,那么只要在读出它时检查它是否为DbNull:
decimal myAppVal = rdr["DbColumn"] == DBNull.Value
? default(decimal)
: (decimal) rdr["DbColumn"];
或显式设置0.0M而不是使用默认(十进制)
设计方面,如果你发现自己经常这样做,那么我建议创建一个通用的扩展方法来读取数据库中的值。这样,您可以确保避免无效的强制转换并处理异常,但更重要的是,如果为空,则返回默认值。 ;)
喜欢的东西(我只是在这里吐痰):
public static T CastFromDbTo<T>(object readerObject)
{
T returnVal = default(T);
if (readerObject is T)
{
var myValue = (T) readerObject;
returnVal = readerObject != DbNull.Value && myValue != null
? (T) readerObject
: default(T);
}
return returnVal;
}
然后你可以像这样抓住你的价值:
var myAppValue = HelperClass.CastFromDbTo<decimal>(rdr["DbColumn"]);
或实际进行扩展:
public static T CastFromDbTo<T>(this object readerObject)
{
T returnVal = default(T);
if (readerObject is T)
{
var myValue = (T) readerObject;
returnVal = readerObject != DbNull.Value && myValue != null
? (T) readerObject
: default(T);
}
return returnVal;
}
然后你可以这样做:
var myAppVal = rdr["DbColumn"].CastFromDbTo<decimal>();
答案 3 :(得分:1)
您为v1指定的值为decimal
,但类型仍为decimal?
。这就是你无法解决的原因。
尝试
decimal v2 = v1.Value;
答案 4 :(得分:1)
Nullable Types具有属性Value
和HasValue
。
HasValue - 获取一个值,该值指示当前Nullable对象是否具有值。
值 - 如果HasValue为true,则包含值,如果不是null。
decimal v2;
if (v1.HasValue) // check for null
{
v2 = v1.Value;
}