navigation
 Monday, October 30, 2006

Campbell, CA - October 30th 2006 - Falafel Software today earned the prestigious Microsoft Gold Partner Certification level.

"It is very exciting to all of us at Falafel to achieve this milestone", said Lino Tadros, President & CEO of Falafel Software "We intend to use the new Gold level to create an even stronger relationship with Microsoft for Training and Consulting in the .NET 3.0 based technologies."
Falafel Software is a Gold Certified Partner with ISV Solution Provider and Mobility competencies.

posted on October 30, 2006  #    by Lino Tadros  Comments [0] Trackback
 Tuesday, October 17, 2006

In my previous blog, I wrote about how to create generic utility classes that would cast or convert any object to a given type, returning a default if the value was DBNull. I quickly discovered that this code will work just fine as long as the passed type is not nullable. For example, this will work:

int i = ConvertDBNull.To<int>( value, 0 );

But this won't:

int? i = ConvertDBNull.To<int?>( value, null );

The line that fails within the To<>() method is this:

return (T) Convert.ChangeType( value, t );

The reason the call to ChangeType() fails is that there are no conversions defined for the Nullable<> struct, a fact that I find rather puzzling, since it would have been quite easy to do. All you have to do is get the underlying type and convert to it instead. We will still cast the result to the nullable version of the type, because casting a value type to its nullable counterpart is allowed. Here is how to extract that underlying type:

How To Detect Nullable Types Using Reflection

First of all, we will need to be able to detect when a nullable type is passed to the conversion method. The .NET Framework doesn't provide anything that explicitly tests for nullable types, but we can use reflection to determine whether a type is nullable or not. The first thing you need to know is that nullable types are implemented by the framework by using a generic struct called Nullable<>. For example, the following two declarations are identical:

int? i;
Nullable<int> i;

Therefore, if a given type is nullable, it is a generic type whose type is Nullable<>.

private static bool IsNullable( Type t )
{
  if ( !t.IsGenericType ) return false;
  Type g = t.GetGenericTypeDefinition();
  return ( g.Equals( typeof( Nullable<> ) ) );
}

Solving The Conversion Problem

Now that we can detect a nullable type when it's passed, we will need to extract the underlying type. The underlying type is the first and only generic argument passed to the Nullable<> struct. Therefore, the underlying type can be obtained like this:

private static Type UnderlyingTypeOf( Type t )
{
  return t.GetGenericArguments()[ 0 ];
}

We simply need to substitute the underlying type for the nullable type in our original code to get the desired results:

public static T To<T>( object value, T defaultValue )
{
  if ( value == DBNull.Value ) return defaultValue;
  Type t = typeof( T );
  if ( IsNullable( t ) )
    t = UnderlyingTypeOf( t );

  return (T) Convert.ChangeType( value, t );
}

But wait! If you use this method to attempt to convert a null value to a nullable type, the result will be an invalid conversion, because you will be trying to convert null to a value type. We'll have to return without converting if the passed value is null:

public static T To<T>( object value, T defaultValue )
{
  if ( value == DBNull.Value ) return defaultValue;
  Type t = typeof( T );
  if ( IsNullable( t ) )
  {
    if ( value == null ) return default( T );
    t = UnderlyingTypeOf( t );
  }

  return (T) Convert.ChangeType( value, t );
}

Finally, we have a method that will convert any type, including nullable types, to any other type, including nullable types. I hope that you've enjoyed today's submission. If you need training or consulting, contact us and get the Falafel team working for you!

 | 
posted on October 17, 2006  #    by Adam Anderson  Comments [1] Trackback
 Friday, October 13, 2006

Oh, DBNull, how you complicate my code! You throw exceptions when I try to cast or convert you, forcing me to litter my code with conditionals that check for you first. Well, your days of plaguing my code with repetitive conditional expressions and operators are at an end, because I just wrote a new utility class that can cast an object to any type, returning a user-defined default value of that same type if the object is DBNull. And thanks to the power of C# 2.0 generics, it only took 7 lines of code. And 4 of those are curly braces.

On a more serious note, this article is really about the same thing as the last one I wrote: how to reduce or eliminate repetitive code. Today's inspiration came from the annoying stock behavior of the DBNull class, which actually goes to the trouble of implementing the IConvertable interface just so it can throw exceptions if any code tries to convert it. The result is that you end up writing a lot of code like this:

// Assume dr is a DataReader
object o = dr[ "Column1" ];
int i = ( o != DBNull.Value ) ? (int) o : 0; // or whatever default value makes sense

Code like this, while innocuous and relatively harmless, just kind of gets to a man after a while. I started to write a class that would test for DBNull before casting to a given type, and it looked kind of like this:

public static class CastDBNull
{
  public static string ToString( object value, string defaultValue )
  {
    return ( value != DBNull.Value ) ? (string) value : defaultValue;
  }
  public static int ToInt32( object value, int defaultValue )
  {
    return ( value != DBNull.Value ) ? (int) value : defaultValue;
  }
  // And so on
}

It didn't take long to recognize a pattern: I was writing the same code over and over again, varying only the type. This calls for generics! The resulting code after applying generics to the problem becomes much more compact:

public static class CastDBNull
{
  public static T To<T>( object value, T defaultValue )
  {
    return ( value != DBNull.Value ) ? (T) value : defaultValue;
  }
}

The generic version takes a type specifier that determines both the return type and the type of the default value. In case generic syntax is still new and strange-looking to you, perhaps an example of how to use this class will help illustrate its power and flexibility:

// Pass string type to cast to string
string s = CastDBNull.To<string>( dr[ "Column1" ], String.Empty );
// Same class, same method, but passing int type allows casting to int
int i = CastDBNull.To<int>( dr[ "Column2" ], 0 );

Calls to this class take a little less typing than the conditional expressions and operators they encapsulate, but more importantly to my fingers, I find them easier to type. I find that writing lots of little utility classes like this makes programming both faster and more enjoyable. Thanks to a flexible method in the Convert class, the same kind of logic can be applied to convert values generically rather than simply casting them:

public static class ConvertDBNull
{
  public static T To<T>( object value, T defaultValue )
  {
    if ( value == DBNull.Value ) return defaultValue;
    return (T) Convert.ChangeType( value, typeof( T ) );
  }
}

I hope that you've enjoyed today's submission. If you need training or consulting, contact us and get the Falafel team working for you!

 | 
posted on October 13, 2006  #    by Adam Anderson  Comments [1] Trackback