object IConvertible.ToType (Type type, IFormatProvider provider)
{
- return System.Convert.ToType (m_value, type, provider);
+ return System.Convert.ToType (m_value, type, provider, false);
}
bool IConvertible.ToBoolean (IFormatProvider provider)
object IConvertible.ToType (Type type, IFormatProvider provider)
{
- return System.Convert.ToType (m_value, type, provider);
+ return System.Convert.ToType (m_value, type, provider, false);
}
bool IConvertible.ToBoolean (IFormatProvider provider)
+2009-03-14 Miguel de Icaza <miguel@novell.com>
+
+ * Convert.cs (ToType): Control whether this internal function will
+ call an IConvertible.ToType method or not.
+
+ Classes and structs implementing IConvertible in mscorlib (the
+ only callers that can access Convert.ToType) must pass false to
+ avoid a infinite recursion problem and callers from the public
+ Convert API must call it with true.
+
+ This fixes the regression reported in #485377 that was introduced
+ by the fix for #481687.
+
+ * Int16.cs, UInt64.cs, Double.cs, Enum.cs, SByte.cs, UInt16.cs,
+ Byte.cs, Decimal.cs, Int32.cs, String.cs, Int64.cs, Char.cs,
+ Boolean.cs, Single.cs, UInt32.cs: Update the call sites.
+
2009-03-07 Gert Driesen <drieseng@users.sourceforge.net>
- * Convert.cs: Do not throw InvalidCastException if IConvertible.ToType
- returns null.
+ * Convert.cs: Do not throw InvalidCastException if
+ IConvertible.ToType returns null.
2009-03-06 Andrés G. Aragoneses <aaragoneses@novell.com>
IConvertible.ToType if there are no other possible conversions
defined.
- Fixes: #481687
+ Fixes: #481687
2009-03-06 Rodrigo Kumpera <rkumpera@novell.com>
object IConvertible.ToType (Type type, IFormatProvider provider)
{
- return System.Convert.ToType (m_value, type, provider);
+ return System.Convert.ToType (m_value, type, provider, false);
}
bool IConvertible.ToBoolean (IFormatProvider provider)
else {
provider = ci.NumberFormat;
}
- return ToType (value, conversionType, provider);
+ return ToType (value, conversionType, provider, true);
}
public static object ChangeType (object value, TypeCode typeCode)
else {
provider = ci.NumberFormat;
}
- return ToType (value, conversionType, provider);
+ return ToType (value, conversionType, provider, true);
}
public static object ChangeType (object value, Type conversionType, IFormatProvider provider)
{
if ((value != null) && (conversionType == null))
throw new ArgumentNullException ("conversionType");
- return ToType (value, conversionType, provider);
+ return ToType (value, conversionType, provider, true);
}
public static object ChangeType (object value, TypeCode typeCode, IFormatProvider provider)
{
Type conversionType = conversionTable [(int)typeCode];
- return ToType (value, conversionType, provider);
+ return ToType (value, conversionType, provider, true);
}
private static bool NotValidBase (int value)
// it as an object. In place for the core data types to use
// when implementing IConvertible. Uses hardcoded indexes in
// the conversionTypes array, so if modify carefully.
- internal static object ToType (object value, Type conversionType,
- IFormatProvider provider)
+
+ //
+ // The `try_target_to_type' boolean indicates if the code
+ // should try to call the IConvertible.ToType method if everything
+ // else fails.
+ //
+ // This should be true for invocations from Convert.cs, and
+ // false from the mscorlib types that implement IConvertible that
+ // all into this internal function.
+ //
+ // This was added to keep the fix for #481687 working and to avoid
+ // the regression that the simple fix introduced (485377)
+ internal static object ToType (object value, Type conversionType, IFormatProvider provider, bool try_target_to_type)
{
if (value == null) {
if ((conversionType != null) && conversionType.IsValueType){
else if (conversionType == conversionTable[18]) // 18 TypeCode.String
return (object) convertValue.ToString (provider);
else {
- return convertValue.ToType (conversionType, provider);
+ if (try_target_to_type)
+ return convertValue.ToType (conversionType, provider);
}
- } else
- // Not in the conversion table
- throw new InvalidCastException ((Locale.GetText (
- "Value is not a convertible object: " + value.GetType().ToString() + " to " + conversionType.FullName)));
+ }
+ // Not in the conversion table
+ throw new InvalidCastException ((Locale.GetText (
+ "Value is not a convertible object: " + value.GetType().ToString() + " to " + conversionType.FullName)));
}
}
}
object IConvertible.ToType (Type type, IFormatProvider provider)
{
- return Convert.ToType (this, type, provider);
+ return Convert.ToType (this, type, provider, false);
}
bool IConvertible.ToBoolean (IFormatProvider provider)
object IConvertible.ToType (Type type, IFormatProvider provider)
{
- return System.Convert.ToType (m_value, type, provider);
+ return System.Convert.ToType (m_value, type, provider, false);
}
bool IConvertible.ToBoolean (IFormatProvider provider)
object IConvertible.ToType (Type type, IFormatProvider provider)
{
- return Convert.ToType (get_value (), type, provider);
+ return Convert.ToType (get_value (), type, provider, false);
}
#if ONLY_1_1
object IConvertible.ToType (Type type, IFormatProvider provider)
{
- return System.Convert.ToType (m_value, type, provider);
+ return System.Convert.ToType (m_value, type, provider, false);
}
#if ONLY_1_1
object IConvertible.ToType (Type type, IFormatProvider provider)
{
- return System.Convert.ToType (m_value, type, provider);
+ return System.Convert.ToType (m_value, type, provider, false);
}
#if ONLY_1_1
object IConvertible.ToType (Type type, IFormatProvider provider)
{
- return System.Convert.ToType (m_value, type, provider);
+ return System.Convert.ToType (m_value, type, provider, false);
}
#if ONLY_1_1
object IConvertible.ToType (Type type, IFormatProvider provider)
{
- return System.Convert.ToType (m_value, type, provider);
+ return System.Convert.ToType (m_value, type, provider, false);
}
ushort IConvertible.ToUInt16 (IFormatProvider provider)
object IConvertible.ToType (Type type, IFormatProvider provider)
{
- return System.Convert.ToType (m_value, type, provider);
+ return System.Convert.ToType (m_value, type, provider, false);
}
#if ONLY_1_1
object IConvertible.ToType (Type type, IFormatProvider provider)
{
- return Convert.ToType (this, type, provider);
+ return Convert.ToType (this, type, provider, false);
}
#if ONLY_1_1
object IConvertible.ToType (Type type, IFormatProvider provider)
{
- return System.Convert.ToType (m_value, type, provider);
+ return System.Convert.ToType (m_value, type, provider, false);
}
#if ONLY_1_1
object IConvertible.ToType (Type type, IFormatProvider provider)
{
- return System.Convert.ToType (m_value, type, provider);
+ return System.Convert.ToType (m_value, type, provider, false);
}
#if ONLY_1_1
object IConvertible.ToType (Type type, IFormatProvider provider)
{
- return System.Convert.ToType (m_value, type, provider);
+ return System.Convert.ToType (m_value, type, provider, false);
}
#if ONLY_1_1
AssertNotNull ("#C1", c3);
AssertEquals ("#C2", 3, c3);
}
+
+ // This is a simple and happy struct.
+ struct Foo {
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidCastException))]
+ public void ChangeType_ShouldThrowOnString ()
+ {
+ Foo f = (Foo) Convert.ChangeType ("this-is-a-string", typeof (Foo));
+ }
}
public class Image