Reputation: 6670
I have a constructor with a signature that looks something like:
public Something(UInt64 uid, UInt64? parentUniqueId)
{
// ...
}
The constructor is called with the result of a database retrieval. It is possible that the parentUniqueId
returns as DBNull
.
Currently, the calling code looks something like:
var s = new Something(uid: Convert.ToUint64(row[0]), ConvertTo.Unit64(row[1]))
That doesn't work, so I tried (in the second cast) to do (Unit64?)row[1]
; but, that is freaking out.
The challenge here is that Something
is a base class that accepts "specified" arguments, e.g. Unit64
and it is being called from an inheriting class that accepts a DataRow
. So, you can imagine:
public SomethingSpecific(DataRow row)
: base(
uid: Convert.ToUInt64(row[0]))
// etc...
)
{ }
Is this possible in one line? How would I handle the DBNull
conversion?
Upvotes: 1
Views: 137
Reputation: 28499
Write your own convert method like this:
public static class MyConvert
{
public static UInt64? ToUInt64OrNull(object value)
{
if(Convert.IsDBNull(value) || value == null)
{
return null;
}
else
{
return Convert.ToUInt64(value);
}
}
}
null
and DBNull
are two very different values. So you have to explicitly handle them both.
Then use it like this:
var s = new Something(uid: Convert.ToUInt64(row[0]), MyConvert.ToUInt64OrNull(row[1]))
It is assumed that row[0]
will never be null
or DBNull
, but that row[1]
can be DBNull
and will be passed as null to the constructor then.
This is how you would use it when writing your child class:
public SomethingSpecific(DataRow row)
: base(
uid: Convert.ToUInt64(row[0]),
parentUniqueId: MyConvert.ToUInt64OrNull(row[1])
// etc...
)
{ }
Upvotes: 3
Reputation: 4865
How about a bit more defensive programming? E.g.
var s = new Something(uid: row[0] != null ? Convert.ToUInt64(row[0]) : default(UInt64), parentUniqueId: row[1] != null ? Convert.ToUInt64(row[1]) : default(UInt64?));
It's not nice but it would do the trick.
Upvotes: 1