C# DBNull从数据集强制转换到可为Null的构造函数

C# DBNull从数据集强制转换到可为Null的构造函数,c#,dbnull,C#,Dbnull,我有一个带有签名的构造函数,它看起来像: public Something(UInt64 uid, UInt64? parentUniqueId) { // ... } var s = new Something(uid: Convert.ToUint64(row[0]), ConvertTo.Unit64(row[1])) 使用数据库检索的结果调用构造函数。parentUniqueId可能返回为DBNull 当前,调用代码类似于: public Something(UInt64 u

我有一个带有签名的构造函数,它看起来像:

public Something(UInt64 uid, UInt64? parentUniqueId)
{
    // ...
}
var s = new Something(uid: Convert.ToUint64(row[0]), ConvertTo.Unit64(row[1]))
使用数据库检索的结果调用构造函数。
parentUniqueId
可能返回为
DBNull

当前,调用代码类似于:

public Something(UInt64 uid, UInt64? parentUniqueId)
{
    // ...
}
var s = new Something(uid: Convert.ToUint64(row[0]), ConvertTo.Unit64(row[1]))
这不起作用,所以我(在第二次试演中)尝试了
(Unit64?)行[1]
;但是,这太离谱了

这里的挑战是
Something
是一个接受“指定”参数的基类,例如
Unit64
,它是从接受
DataRow
的继承类调用的。所以,你可以想象:

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?));

这不好,但它会起作用

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

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);
        }

    }
}
var s = new Something(uid: Convert.ToUInt64(row[0]), MyConvert.ToUInt64OrNull(row[1]))
null
DBNull
是两个非常不同的值。所以你必须明确地处理这两个问题

然后像这样使用它:

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

    }
}
var s = new Something(uid: Convert.ToUInt64(row[0]), MyConvert.ToUInt64OrNull(row[1]))
假定
行[0]
永远不会是
null
DBNull
,但
行[1]
可以是
DBNull
,然后将作为null传递给构造函数

以下是编写子类时如何使用它:

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

编写自己的转换方法,如下所示:

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

    }
}
var s = new Something(uid: Convert.ToUInt64(row[0]), MyConvert.ToUInt64OrNull(row[1]))
null
DBNull
是两个非常不同的值。所以你必须明确地处理这两个问题

然后像这样使用它:

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

    }
}
var s = new Something(uid: Convert.ToUInt64(row[0]), MyConvert.ToUInt64OrNull(row[1]))
假定
行[0]
永远不会是
null
DBNull
,但
行[1]
可以是
DBNull
,然后将作为null传递给构造函数

以下是编写子类时如何使用它:

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


为什么不使用或映射器?如果结果为第[0]行包含空值,您希望存储什么?数据集的默认值为dbnull,是否可以将默认值更改为使您的代码满意的值?@CF5如果可能的话,只需使用空值。我会使用类似于:var s=new something(uid:Convert.IsDBNull(第[0]行))?空值:Convert.ToUint64(第[4行[0]),ConvertTo.Unit64(第[1]行);为什么不使用or映射器?如果结果是第[0]行包含null,您希望存储什么?数据集的默认值是dbnull,是否可以将默认值更改为令代码满意的值?@CF5如果可能的话,只需使用null。我将使用类似于:var s=new something(uid:Convert.IsDBNull(第[0]行)的内容?null:Convert.ToUint64(第[0]行),ConvertTo.Unit64(第[1]行);这感觉更可靠一些。你认为有必要解释
null
吗?或者你认为我可以采用类似于另一个答案的一行方法吗?特别是考虑到
SomethingSpecific
的构造函数。安全性比抱歉好。而且当你有自己的转换函数时,你可以轻松地在不同的地方使用它。我添加了要在SomethingSpecific构造函数中使用的代码。这感觉更加健壮。你认为有必要解释
null
吗?或者你认为我可以使用类似于另一个答案所发布的一行方法吗?特别是考虑到
SomethingSpecific.比抱歉更安全。当你拥有自己的转换函数时,你可以在不同的地方轻松地重用它。我添加了代码,以用于特定于Something的构造函数。我喜欢这样。我认为;但是,
default
调用可能需要是
null
@Thomas:这将在第二种情况下。默认值是b基于类型。我喜欢这样。我认为;
default
调用可能需要是
null
@Thomas:在第二种情况下会是这样。默认值是根据类型选择的。