static object ChangeType (object value, TypeSpec targetType, out bool error)
{
IConvertible convert_value = value as IConvertible;
if (convert_value == null) {
error = true;
return null;
}
//
// We cannot rely on build-in type conversions as they are
// more limited than what C# supports.
// See char -> float/decimal/double conversion
//
error = false;
try {
switch (targetType.BuiltinType) {
case BuiltinTypeSpec.Type.Bool:
return convert_value.ToBoolean (nfi);
case BuiltinTypeSpec.Type.Byte:
return convert_value.ToByte (nfi);
case BuiltinTypeSpec.Type.Char:
return convert_value.ToChar (nfi);
case BuiltinTypeSpec.Type.Short:
return convert_value.ToInt16 (nfi);
case BuiltinTypeSpec.Type.Int:
return convert_value.ToInt32 (nfi);
case BuiltinTypeSpec.Type.Long:
return convert_value.ToInt64 (nfi);
case BuiltinTypeSpec.Type.SByte:
return convert_value.ToSByte (nfi);
case BuiltinTypeSpec.Type.Decimal:
if (convert_value.GetType () == typeof (char))
return (decimal) convert_value.ToInt32 (nfi);
return convert_value.ToDecimal (nfi);
case BuiltinTypeSpec.Type.Double:
if (convert_value.GetType () == typeof (char))
return (double) convert_value.ToInt32 (nfi);
return convert_value.ToDouble (nfi);
case BuiltinTypeSpec.Type.Float:
if (convert_value.GetType () == typeof (char))
return (float) convert_value.ToInt32 (nfi);
return convert_value.ToSingle (nfi);
case BuiltinTypeSpec.Type.String:
return convert_value.ToString (nfi);
case BuiltinTypeSpec.Type.UShort:
return convert_value.ToUInt16 (nfi);
case BuiltinTypeSpec.Type.UInt:
return convert_value.ToUInt32 (nfi);
case BuiltinTypeSpec.Type.ULong:
return convert_value.ToUInt64 (nfi);
case BuiltinTypeSpec.Type.Object:
return value;
}
} catch {
}
error = true;
return null;
}