private static bool check_type (Type from, Type to) {
if (from == to)
return true;
if (from == null)
return true;
if (to.IsByRef != from.IsByRef)
return false;
if (to.IsInterface)
return to.IsAssignableFrom (from);
if (to.IsEnum) {
to = Enum.GetUnderlyingType (to);
if (from == to)
return true;
}
#if NET_2_0
if (to.IsGenericType && to.GetGenericTypeDefinition () == typeof (Nullable<>) && to.GetGenericArguments ()[0] == from)
return true;
#endif
TypeCode fromt = Type.GetTypeCode (from);
TypeCode tot = Type.GetTypeCode (to);
switch (fromt) {
case TypeCode.Char:
switch (tot) {
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.Int32:
case TypeCode.UInt64:
case TypeCode.Int64:
case TypeCode.Single:
case TypeCode.Double:
return true;
}
return to == typeof (object);
case TypeCode.Byte:
switch (tot) {
case TypeCode.Char:
case TypeCode.UInt16:
case TypeCode.Int16:
case TypeCode.UInt32:
case TypeCode.Int32:
case TypeCode.UInt64:
case TypeCode.Int64:
case TypeCode.Single:
case TypeCode.Double:
return true;
}
return to == typeof (object) || (from.IsEnum && to == typeof (Enum));
case TypeCode.SByte:
switch (tot) {
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Single:
case TypeCode.Double:
return true;
}
return to == typeof (object) || (from.IsEnum && to == typeof (Enum));
case TypeCode.UInt16:
switch (tot) {
case TypeCode.UInt32:
case TypeCode.Int32:
case TypeCode.UInt64:
case TypeCode.Int64:
case TypeCode.Single:
case TypeCode.Double:
return true;
}
return to == typeof (object) || (from.IsEnum && to == typeof (Enum));
case TypeCode.Int16:
switch (tot) {
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Single:
case TypeCode.Double:
return true;
}
return to == typeof (object) || (from.IsEnum && to == typeof (Enum));
case TypeCode.UInt32:
switch (tot) {
case TypeCode.UInt64:
case TypeCode.Int64:
case TypeCode.Single:
case TypeCode.Double:
return true;
}
return to == typeof (object) || (from.IsEnum && to == typeof (Enum));
case TypeCode.Int32:
switch (tot) {
case TypeCode.Int64:
case TypeCode.Single:
case TypeCode.Double:
return true;
}
return to == typeof (object) || (from.IsEnum && to == typeof (Enum));
case TypeCode.UInt64:
case TypeCode.Int64:
switch (tot) {
case TypeCode.Single:
case TypeCode.Double:
return true;
}
return to == typeof (object) || (from.IsEnum && to == typeof (Enum));
case TypeCode.Single:
return tot == TypeCode.Double || to == typeof (object);
default:
/* TODO: handle valuetype -> byref */
if (to == typeof (object) && from.IsValueType)
return true;
if (to.IsPointer && from == typeof (IntPtr))
return true;
return to.IsAssignableFrom (from);
}
}