LogoASPAlliance: Articles, reviews, and samples for .NET Developers
CodeSnip: Convert.ChangeType Wrapper that Handles Nullable Types
by Peter Johnson
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 32630/ 71

A known problem with the useful late-bound casting method Convert.ChangeType is that it doesn’t handle nullable types. I discovered this problem several months ago, talked to the CLR team at Microsoft about it, blogged about it, and have now written and tested a wrapper method that does handle nullable types. Hopefully, a future .NET Framework service pack will include this functionality, so this method can be deleted and calls to it can be changed to call Convert.ChangeType directly again.

Listing 1 – An improved ChangeType method

/// <summary>
/// Returns an Object with the specified Type and whose value is equivalent to the specified object.
/// </summary>
/// <param name="value">An Object that implements the IConvertible interface.</param>
/// <param name="conversionType">The Type to which value is to be converted.</param>
/// <returns>An object whose Type is conversionType (or conversionType's underlying type if conversionType
/// is Nullable&lt;&gt;) and whose value is equivalent to value. -or- a null reference, if value is a null
/// reference and conversionType is not a value type.</returns>
/// <remarks>
/// This method exists as a workaround to System.Convert.ChangeType(Object, Type) which does not handle
/// nullables as of version 2.0 (2.0.50727.42) of the .NET Framework. The idea is that this method will
/// be deleted once Convert.ChangeType is updated in a future version of the .NET Framework to handle
/// nullable types, so we want this to behave as closely to Convert.ChangeType as possible.
/// This method was written by Peter Johnson at:
/// </remarks>
public static object ChangeType(object value, Type conversionType)
// Note: This if block was taken from Convert.ChangeType as is, and is needed here since we're
// checking properties on conversionType below.
  if (conversionType == null)
    throw new ArgumentNullException("conversionType");
  } // end if
// If it's not a nullable type, just pass through the parameters to Convert.ChangeType
  if (conversionType.IsGenericType && 
// It's a nullable type, so instead of calling Convert.ChangeType directly which would throw a
// InvalidCastException (per,
// determine what the underlying type is
// If it's null, it won't convert to the underlying type, but that's fine since nulls don't really
// have a type--so just return null
// Note: We only do this check if we're converting to a nullable type, since doing it outside
// would diverge from Convert.ChangeType's behavior, which throws an InvalidCastException if
// value is null and conversionType is a value type.
    if (value == null)
      return null;
    } // end if
// It's a nullable type, and not null, so that means it can be converted to its underlying type,
// so overwrite the passed-in conversion type with this underlying type
    NullableConverter nullableConverter = new NullableConverter(conversionType);
    conversionType = nullableConverter.UnderlyingType;
  } // end if
// Now that we've guaranteed conversionType is something Convert.ChangeType can handle (i.e. not a
// nullable type), pass the call on to Convert.ChangeType
  return Convert.ChangeType(value, conversionType);

Special thanks to fellow ASPAlliance author J. Ambrose Little and alert reader Toby Johnson for helping me put together this method.

©Copyright 1998-2020  |  Page Processed at 2020-07-05 4:08:39 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search