in ClearScript/Util/TypeHelpers.cs [166:252]
public static bool IsAssignableFrom(this Type type, ref object value)
{
if (type.IsByRef)
{
type = type.GetElementType();
}
if (type.IsNullable())
{
return (value == null) || (Nullable.GetUnderlyingType(type).IsAssignableFrom(ref value));
}
if (value == null)
{
return !type.IsValueType;
}
var valueType = value.GetType();
if ((valueType == type) || type.IsAssignableFrom(valueType))
{
return true;
}
if (type.IsImplicitlyConvertibleFrom(valueType, ref value))
{
return true;
}
if (!type.IsValueType)
{
if (type.IsInterface && type.IsImport && valueType.IsCOMObject)
{
var result = false;
var pUnknown = Marshal.GetIUnknownForObject(value);
var iid = type.GUID;
if (iid != Guid.Empty)
{
if (HResult.Succeeded(Marshal.QueryInterface(pUnknown, ref iid, out var pInterface)))
{
Marshal.Release(pInterface);
result = true;
}
}
Marshal.Release(pUnknown);
return result;
}
return false;
}
if (!valueType.IsValueType)
{
return false;
}
if (type.IsEnum)
{
return Enum.GetUnderlyingType(type).IsAssignableFrom(ref value) && (value.DynamicCast<int>() == 0);
}
if (valueType.IsEnum)
{
return false;
}
if (type.IsNumeric(out var typeIsIntegral))
{
if (typeIsIntegral)
{
if (!valueType.IsIntegral())
{
return false;
}
}
else if (!valueType.IsNumeric())
{
return false;
}
value = Convert.ChangeType(value, type);
return true;
}
return false;
}