3

在我的数据库中,v1 字段是可为空的字段。但如果值为空,我定义 0 (默认)。

public decimal? v1 {
  get {
    return this._v1; 
  }
  set {
    this._v1 = value ?? 0M;
  }
}

所以现在, v1 不再是可为空的变量。

但我不能这样做,

decimal v2 = v1;

错误消息说,不能隐式转换类型“十进制?” 为“十进制”。

在这种情况下,我是否必须像这样转换为十进制?

decimal v2 = Convert.ToDecimal(v1);

这是非常烦人的工作。代码看起来也很脏。

有人知道更好的解决方案吗?请给我建议。

4

5 回答 5

18

不,您不必转换decimal?,您可以从类型访问基础值,Nullable例如

decimal v2 = v1.Value;

为类型分配默认值Nullable并不使其不可为空,它只是意味着它有一个值。可空类型有一个HasValue属性可以帮助您确定这一点。

只是为了记录,我不建议将值默认为0它可能更有意义,让它默认null考虑它确实可以为空。如果您需要在您的应用程序中有一个默认值,您可能需要使用该GetValueOrDefault方法,例如

decimal v2 = v1.GetValueOrDefault(0m);
于 2012-09-18T15:22:03.797 回答
8

decimal?将 a 转换为decimal但值为0when的最简单方法null,您可以执行以下操作:

decimal? a = null;
decimal b = a.GetValueOrDefault(0m); // will contain 0 when null, otherwise the value

阅读GetValueOrDefault

您也可以GetValueOrDefault不带参数调用,这将产生default(T),在 Decimal 的情况下为 0,但我喜欢明确。

于 2012-09-18T15:24:52.813 回答
5

我很好奇您为什么要将您的应用程序代码变量定义为可为空,但如果它为空则将其设置为 0。如果将空值从数据库传递到您的应用程序变量,是否只是为了避免异常?如果您的应用程序并不绝对需要可为空的十进制变量,只需在读取它时检查它是否存在 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>();
于 2012-09-18T15:59:13.517 回答
1

您分配给 v1 的值是decimal,但类型仍然是decimal?。这就是为什么你不能评估它。

尝试

decimal v2 = v1.Value;
于 2012-09-18T15:22:37.513 回答
1

可空类型具有属性ValueHasValue

HasValue - 获取一个值,该值指示当前 Nullable 对象是否有值。

Value - 如果 HasValue 为 true,则如果不是 null,则它包含该值。

decimal v2;

if (v1.HasValue) // check for null
{
  v2 = v1.Value;
}

查看MSDN - Nullable 类型(C# 编程指南)

于 2012-09-18T15:23:32.863 回答