best way to prevent Null failure with string casting
Solution 1
Use the null-coalescing operator: ??
callReportCode = (reader["Call Report Code"] ?? "").ToString();
If the data in your field is DBNull.Value
(rather than null
), this will still work, because DBNull.Value
is not null
, so the ??
won't be used, and DBNull.Value.ToString()
is ""
, which is what you'd want.
Solution 2
Convert.ToString(reader["Call Report Code"]);
It will return string.Empty
if the value is null.
Source: http://msdn.microsoft.com/en-us/library/astxcyeh.aspx
Update: it also works with DBNull
, I've just verified.
Update 2: I decided to bring a more complete test here, just to be sure:
DBNull dbNull = null;
DBNull dbNullEmpty = DBNull.Value;
string stringNull = null;
string stringEmpty = string.Empty;
var outcome1 = Convert.ToString(dbNull);//Empty string
var outcome2 = Convert.ToString(dbNullEmpty);//Empty string
var outcome3 = Convert.ToString(stringNull);//NULL
var outcome4 = Convert.ToString(stringEmpty);//Empty string
Solution 3
My suggestion is to never convert ToString
when the data isn't a string, and if the data is already a string, then calling ToString
is redundant, and a cast is all that's required.
I am making an assumption that the datatype in the database is integer, in which case, you can use a nullable int.
int? accountNumber = reader["Account Number"] == DBNull.Value ? null : (int?)reader["Account Number"];
I have made an extension method to do just this thing.
public static class SqlDataReaderExtensions
{
public static T Field<T>(this SqlDataReader reader, string columnName)
{
object obj = reader[columnName];
if (obj == null)
{
throw new IndexOutOfRangeException(
string.Format(
"reader does not contain column: {0}",
columnName
)
);
}
if (obj is DBNull)
{
obj = null;
}
return (T)obj;
}
}
Usage
int? accountType = reader.Field<int?>("Account Number"); // will return NULL or the account number.
Solution 4
If your string is nullable, you need to check the value returned from the SqlDataReader
against DBNull.Value
:
_callReportCode = reader["Call Report Code"] as string;
If the object returned by reader["Call Report Code"]
is not a string
, it's DBNull.Value
, so the as
cast is going to set the value of _callReportCode
to null
as well.
If you must set the string to a non-null in case the database value is missing, add ??
, like this:
_callReportCode = (reader["Call Report Code"] as string) ?? string.Empty;
Solution 5
i have some easiest and common Method.
public static string ToNULLString(this string Values)
{
if (string.IsNullOrEmpty(Values))
{
return "";
}
else
{
return Values.ToString();
}
}
use in C#
string item = null;
string value = item.ToNULLString();
jth41
Updated on February 07, 2020Comments
-
jth41 about 4 years
_callReportCode = reader["Call Report Code"].ToString();
I am attempting to handle the possibility for the object I am calling ToString on to be NULL. I am going to be using the above statement with several variables and I dont want to make an individual try/catch for each one... what is the best way to do null checking for strings.
Other datatypes ive been doing this:
int.TryParse(reader["Account Number"].ToString(), out _accountNumber);
In this code "reader" refers to a SqlDataReader but thats not really important for this question.
-
Admin about 11 yearsIt will throw NPE if the object is null
-
Bobson about 11 years@0A0D - It'll only throw an exception if
reader
is null. This will work correctly ifreader["Call Report Code"]
is null. -
Matthew about 11 yearsIf the data is
DBNull
, you cannot use the null coalescing operator. -
jth41 about 11 yearsWhat do you do with the value later? like if I am going to pass it into a constructor? do I have to change that constructor to take a nullable int?
-
Bobson about 11 years@Matthew - Sure you can.
DBNull.Value.ToString()
returns""
. -
Matthew about 11 yearsThat depends on your application, what does it mean to your application when
Account Number
is null? -
Andre Calil about 11 years
(DBNull.Value ?? "").ToString()
doesn't even compile -
Matthew about 11 yearsif the reader returns null for that column name, it means the column itself doesn't exist, if it returns DBNull, it means the database returned a null value. They are two distinct things, one is an application problem (you're requesting a column that doesn't exist), and the other isn't (column values can be null [DBNull]).
-
Bobson about 11 years@AndreCalil - That doesn't compile, but
reader["Call Report Code"]
is of typeobject
, so the actual scenario will. -
Andre Calil about 11 years@Bobson Yes, but
DBNull
inherits fromObject
(msdn.microsoft.com/en-us/library/system.dbnull.aspx). I can see that you've never used it in a real project. It will returnDBNull
from the DB if the column is null, it's a very usual problem. -
Matthew about 11 yearsYou cannot convert
object
tostring
using the null coalescing, you could cast it to string, however if the underlying data is neithernull
(notDBNull
) norstring
, you will get a cast exception. If you try and castDBNull
to string, you will get a cast exception. -
Bobson about 11 years@Matthew -
object foo = DateTime.Now; (foo ?? "").ToString();
works.object foo = 2.3; (foo ?? "").ToString();
works.object foo = null; (foo ?? "").ToString();
works.object foo = DBnull.Value; (foo ?? "").ToString();
works. Give me an example where you get an exception with this pattern. -
jth41 about 11 yearsIt still throws an exception when I try this... _callReportCode = Convert.ToString(reader["Call Report Code"]); the whole point is to get it in that variable
-
Andre Calil about 11 years@John Can you share details of the exception?
-
Matthew about 11 yearsSorry, I was using an erroneous example of
string x = y ?? "";
, I was missing theToString
portion. -
Bobson about 11 years@Matthew - It's ok, I've been there. I'm sorry I got so defensive about it. I use this pattern a lot, so I was pretty confident in it.
-
Matthew about 11 yearsNo need to apologize, I was the one who made this mistake.
-
Mohit Jain almost 10 yearsPlease explain your answer in very brief.
-
Anil over 7 yearsit does not seems to be working the way msdn says, can be checked by Convert.ToString(null).EndsWith(""); vs string.empty.EndsWith(""); The stmt Convert.ToString(null).EndsWith("") will throw object ref exception.
-
Andre Calil over 7 years@AnilKumar yeah, but that's kinda expected.
Convert.ToString(null)
returns null, then you try to call the method.EndsWith("")
from it. -
Anil over 7 yearsIt will not return string.Empty if the value is null, it will return null.
-
Andre Calil over 7 years@AnilKumar I've updated the answer to bring all the situations, please check it out. Thanks!