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
Return convert. 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);
}< br> If (! Type. isinterface & type. isgenerictype) {
type innertype = type. getgenericarguments () [0];
Object innervalue = queryhelper. changetype (value, innertype);
return activator. createinstance (type, new object [] {innervalue});
}< br> If (value is string & type = typeof (guid )) return new GUID (value as string);
If (value is string & type = typeof (Version) return new version (value 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.
Thanks was looking into this issue ..
How about this as an option?
Public static class converter {
Public static t changetype <t> (object Value ){
Typeconverter Tc = typedescriptor. getconverter (typeof (t ));
Return (t) TC. convertfrom (value );
}
Public static void registertypeconverter <T, TC> () Where TC: typeconverter {
Typedescriptor. addattributes (typeof (t), new typeconverterattribute (typeof (TC )));
}
}
This allows you to create new typedescriptors and add them at runtime, for any missing converters e.g. Version
Public class versionconverter: typeconverter
{
Public override object convertfrom (itypedescriptorcontext context, system. Globalization. cultureinfo culture, object Value ){
String strvalue = value as string;
If (strvalue! = NULL ){
Return new version (strvalue );
}
Else {
Return new version ();
}
}
}
Test code...
Static void main (string [] ARGs ){
Converter. registertypeconverter <version, versionconverter> ();
Int? I = converter. changetype <Int?> ("123 ");
Datetime dt = converter. changetype <datetime> ("20:33 ");
Char c = converter. changetype <char> ("X ");
Guid G = converter. changetype <guid> ("{32f92eeb-a703-4eb7-a9f8-62e09f87d03f }");
Version V = converter. changetype <version> ("1.2.3.4 ");
Datetime? K = converter. changetype <datetime?> (Null );
}
I slightly modified your http://aspalliance.com/852 code. I canno tput code there due to server error.
I modified your code slightly, to make it generic. Thanks!
Public static t changetype <t> (object Value ){
Type conversiontype = typeof (t );
If (conversiontype. isgenerictype &&
Conversiontype. getgenerictypedefinition (). Equals (typeof (nullable <> ))){
If (value = NULL) {return default (t );}
Conversiontype = nullable. getunderlyingtype (conversiontype );;
}
Return (t) convert. changetype (value, conversiontype );
}