Use Convert Class Instead of Casting or CType
Convert Class is More Forgiving
How can I handle DBNull in both C# and VB.NET when I don't necessarily know the type of the data without looking up the type of every field in the query result?
I wrote an article on this previously, but I will go into this with a little more detail this time to show you how to handle many of the problems with DBNull automatically.
If you have not learned it already, you will and it will be a hard lesson. You must handle null data coming from database. It is fairly common to have fields in database tables that allow nulls. When this is done, your application must be prepared to handle the occurrence of null data.
As I have said in a previous article, I usually have a set of utility functions that automatically convert null fields to a default value for the type of data expected. Take the following function that converts a null string field to an empty string when a null value is encountered.
public static string MNS(object s)
{
if(s==System.DBNull.Value)
return string.Empty;
else
return Convert.ToString(s);
}
|
or the following function that returns 0 for null or converts the object value to int if it is not null.
public static int MNI(object i)
{
if(i==System.DBNull.Value)
return 0;
else
return (int)i;
}
|
The MNI function will work fine as long as the input data object is of type int. However, it the data object were of type bit or byte, then an Invalid Cast Exception is thrown, even though the resultant data would fit well within Int32. The solution to this delimena is to substitute the use of the Convert Class instead of the direct cast as shown above. The new function is shown below:
public static int MNI(object i)
{
if(i==System.DBNull.Value)
return 0;
else
return Convert.ToInt32(i);
}
|
In VB.NET, the equivelant code for the first MNI might use DirectCast. This code has the same weakness as the first MNI in C# shown above. There are two alternatives in VB.NET. One is to use the Convert Class or the more obvious is to use the CType function, which most VB.NET developers learn first.
In the following example code, you will see the advantage of having a set of utility functions for handling nulls. The following sequence handles the conversion of a byte field to string in the case where the value is not null. The field "required_hours" is a byte field in the database. It could just as well be a bit field, if only a 0 or 1 were needed. But, if you attempted to case via (int), the cast will fail.
if(dt.Rows[0]["required_hours"]!=System.DBNull.Value)
this.txtReqHours.Text=Convert.ToByte(dt.Rows[0]
["required_hours"]).ToString();
|
The code above can actually be replaced with one line of in-line code if I have a set of null handling utility functions as shown by the following line of code. For the purist, the code shown above will run just a bit faster than the line shown below, but when you start taking into consideration the speed of modern computers and compare the time saved by the developer in writing code, I will always opt for the code shown below.
this.txtReqHours = Util.MNI(dt.Rows[0]["required_hours"]);
|
You can take this concept and write as many utility functions as you need, but you get picture of what I am trying to convey here. My major point is that the Convert class is much more flexible and safe than a cast in C# or DirectCast in VB.NET.