Convert.ChangeType doesn't handle nullables
I had an assembly, originally written against .NET 1.1 and now running
on .NET 2.0, that tried to convert a boxed DateTime object to a
Nullable<DateTime> (DateTime?) object, using the
Convert.ChangeType method. When this code runs, I get this exception:
Invalid cast from 'System.DateTime' to '
System.Nullable`1[[System.DateTime, mscorlib, Version=18.104.22.168,
System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider) +864
System.DateTime.System.IConvertible.ToType(Type type, IFormatProvider provider) +36
System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) +433
System.Convert.ChangeType(Object value, Type conversionType) +38
Since a DateTime can be assigned to a nullable DateTime, it didn't make sense to me why it couldn't
be converted to one, by calling Convert.ChangeType(Object, Type)
with a Nullable as the second parameter. A Google search
showed that Paul Wilson
, Cameron Beccario
, and others ran into this too during the beta timeframe.
The CLR team at Microsoft confirmed that this is a known problem:
Convert is not very extensible and was designed around a fixed set of
types to address a specific functionality requirement for VB.
System.ComponentModel has a more comprehensive data type conversion
model, and I believe does deal with nullable.
The docs showed a lot of System.ComponentModel classes for conversion, e.g. DecimalConverter
but unfortunately I couldn't use those in this particular case, since
it doesn't support the late-bound casting that code was doing. It was
disappointing that this particular case wasn't handled, but it's
probably a rare case, and it's understandable given some of the changes to nullables that came so late in the game
My workaround in the short term was to not use the Nullable type for
that particular method, until I could dig into System.ComponentModel
more to find an alternative, or a patch is released for
Convert.ChangeType to handle nullables.
: I've now implemented a wrapper that handles nullables correctly