Wednesday, July 22, 2015

Nullable Types and Casting

Situation: You have non-string types  in the database that can be null. You are simply trying to populate a view, so you are assigning the model properties.  (this is one of the most elementary processes in all web programming)


Remember, we are dealing with a NULLABLE TYPE in our model:
....
public class myModel{
 public int? myProperty  {get;set;}
....

For my example, I'm using int types, but applies to double,  DateTime, etc.

Problem:
If you do the most intuitive:
myModel.myProperty = dr["myProperty"]
you will be told you "cannot implicity convert type object to int" ... "are you missing a cast?"

So you try a cast:

myModel.myProperty = (int?) dr["myProperty"]

But even though you had been smart enough to use the nullable indicator in your explicit cast (the question mark, ?), you will still get "InvalidCastException".

At this point you might be smart enough to attempt this with TryParse along with the Ternary Operator (otherwise you have to use multiple lines of code, though you still have to use at least two since you need to create the out variable, as the out variable is not allowed to be a property):

int tmpInt;
myModel.myProperty = Int.TryParse(dr["myProperty"].ToString(),out tmpInt) ? tmpInt : null

But !surprise!, you won't be allowed to build this.  The compiler doesn't seem to understand that we are dealing with a nullable type.

At this point you might just resort to using TryCatch:
SAD
try{
   myModel.myProperty = Convert.ToInt(dr["myProperty"].ToString());
}
catch{
  myModel.myProperty = null;
}

But it turns out, if you knew this trick, you could get the TryParse n' Ternary option to work:

int tmpInt;
myModel.myProperty = Int.TryParse(dr["myProperty"].ToString(),out tmpInt) ? tmpInt : (int?)null

Can you spot the difference? :)

No comments: