When convert. changetype encounters nullable <t>, an invalidcastexception occurs during conversion. I searched the internet and found the solution as follows:
Code
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 &&
Conversiontype. getgenerictypedefinition (). Equals ( Typeof (Nullable <> )))
{
// It's a nullable type, so instead of calling convert. changetype directly which wowould throw
// Invalidcastexception (per Http://weblogs.asp.net/pjohnson/archive/2006/02/07/437631.aspx ),
// 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 re converting to a nullable type, since doing it outside
// Wocould 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 = New Nullableconverter (conversiontype );
Conversiontype = Nullableconverter. underlyingtype;
} // End if
//Now that we 've guaranteed conversiontype is something convert. changetype can handle (I. e. Not
//Nullable type), pass the call on to convert. changetype
ReturnConvert. changetype (value, conversiontype );
}
Code
Here ' S my uugly generic changetype method (from my ormapper ):
Static Public Object Changetype ( Object Value, type ){
If (Value = Null && Type. isgenerictype) Return Activator. createinstance (type );
If (Value = Null ) Return Null ;
If (Type = Value. GetType ()) Return Value;
If (Type. isenum ){
If (Value Is String )
Return Enum. parse (type, Value As String );
Else
Return Enum. toobject (type, value );
}
If ( ! Type. isinterface && Type. isgenerictype ){
Type innertype = Type. getgenericarguments ()[ 0 ];
Object Innervalue = Queryhelper. changetype (value, innertype );
Return Activator. createinstance (type, New Object [] {Innervalue });
}
If (Value Is String && Type = Typeof (Guid )) Return New GUID (Value As String );
If (Value Is String && Type = Typeof (Version )) Return New Version (Value As String );
If ( ! (Value Is Iconvertible )) Return Value;
Return Convert. changetype (value, type );
}
It may have more than you need, and there are bound to be even more special cases like guid and version, but it works so far.