DBNull 从 DataSet Cast 到 Nullable 构造函数

DBNull From DataSet Cast to Nullable Constructor

我有一个构造函数,其签名类似于:

public Something(UInt64 uid, UInt64? parentUniqueId)
{
    // ...
}

使用数据库检索的结果调用构造函数。有可能 parentUniqueId returns 为 DBNull.

目前,调用代码类似于:

var s = new Something(uid: Convert.ToUint64(row[0]), ConvertTo.Unit64(row[1]))

那行不通,所以我尝试(在第二次投射中)(Unit64?)row[1];但是,这太吓人了。

这里的挑战是 Something 是一个接受 "specified" 参数的基础 class,例如Unit64 并且它是从接受 DataRow 的继承 class 调用的。所以,你可以想象:

public SomethingSpecific(DataRow row)
    : base(
        uid: Convert.ToUInt64(row[0]))
        // etc...
     )
{ }

一行可以吗?我将如何处理 DBNull 转换?

多一点防御性编程怎么样?例如

var s = new Something(uid: row[0] != null ? Convert.ToUInt64(row[0]) : default(UInt64), parentUniqueId: row[1] != null ? Convert.ToUInt64(row[1]) : default(UInt64?));

这不是很好,但可以解决问题。

像这样编写自己的转换方法:

public static class MyConvert
{
    public static UInt64? ToUInt64OrNull(object value)
    {
        if(Convert.IsDBNull(value) || value == null)
        {
            return null;
        }
        else
        {
            return Convert.ToUInt64(value);
        }

    }
}

nullDBNull 是两个截然不同的值。所以你必须明确地处理它们。

然后像这样使用它:

var s = new Something(uid: Convert.ToUInt64(row[0]), MyConvert.ToUInt64OrNull(row[1]))

假定 row[0] 永远不会是 nullDBNull,但 row[1] 可以是 DBNull 并且将作为 null 传递给然后是构造函数。

这就是您编写 child class:

时的用法
public SomethingSpecific(DataRow row)
    : base(
        uid: Convert.ToUInt64(row[0]),
        parentUniqueId: MyConvert.ToUInt64OrNull(row[1])
        // etc...
     )
{ }