繁体   English   中英

C#,Nullable十进制

[英]C#, Nullable decimal

在我的数据库中,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);

这是非常讨厌的工作。 而且代码看起来也很脏。

谁知道更好的解决方案 请指教。

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

decimal v2 = v1.Value;

Nullable类型分配默认值不会使其不可为空,它只是意味着它具有值。 Nullable类型具有HasValue属性,可帮助您确定此属性。

只是为了记录在案,我不会推荐值默认为0 ,它可能会更有意义让它默认为null考虑到它确实可以为null。 如果您需要在应用程序中使用默认值,则可能需要使用GetValueOrDefault方法,例如

decimal v2 = v1.GetValueOrDefault(0m);

转换decimal?的最简单方法是decimal? 对于decimal但是当null0时,您可以执行以下操作:

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

阅读GetValueOrDefault

你也可以调用没有参数的GetValueOrDefault ,它将产生default(T) ,在Decimal的情况下是0,但我喜欢显式。

我很好奇为什么你要将你的应用程序代码变量定义为可空,但如果它为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>();

您为v1指定的值是decimal ,但类型仍为decimal? 这就是你无法解决的原因。

尝试

decimal v2 = v1.Value;

Nullable Types具有ValueHasValue属性。

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

- 如果HasValue为true,则包含值,如果不为null。

decimal v2;

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM