Hi,

I've detected a problem with type convertion when using the TypeConverters
for a type. My initial test case for comparing Mono 2.4.* and trunk results
with the .Net framework was as such:

-- code --
using System;
using System.ComponentModel;

namespace PrimitiveTests
{
    class Program
    {
        static void Main(string[] args)
        {
            Type[] types = { typeof(Boolean),
                               typeof(Byte),
                               typeof(SByte),
                               typeof(Int16),
                               typeof(UInt16),
                               typeof(Int32),
                               typeof(UInt32),
                               typeof(Int64),
                               typeof(UInt64),
                               typeof(IntPtr),
                               typeof(UIntPtr),
                               typeof(Char),
                               typeof(Double),
                               typeof(Single)};

            foreach(Type type in types)
                Console.WriteLine("CanConvert " + type + " to Int32? " +
TypeDescriptor.GetConverter(type).CanConvertTo(typeof(Int32)));


Console.WriteLine(TypeDescriptor.GetConverter(typeof(uint)).ConvertTo((uint)134,
typeof(int)));

            Console.ReadKey();
        }
    }
}
-- code --

This revealed that all primitives with a few exceptions (bool, intptr, char)
should be allowed to be converted and Mono's CanConvertTo (and the actual
conversion) was failing. I've created a patch and necessary unit tests to
fix the issue and tested both with the previous script and with my (now
patched) Mono 2.4.3 server's install.

If someone could review, it would be appreciated. I can commit if the
maintainer approves the code.

Regards,

-- 
Alexandre Gomes
http://www.alexandre-gomes.com
Index: class/System/Test/System.ComponentModel/ByteConverterTests.cs
===================================================================
--- class/System/Test/System.ComponentModel/ByteConverterTests.cs	(revision 149643)
+++ class/System/Test/System.ComponentModel/ByteConverterTests.cs	(working copy)
@@ -41,6 +41,7 @@
 		{
 			Assert.IsTrue (converter.CanConvertTo (typeof (string)), "#1");
 			Assert.IsFalse (converter.CanConvertTo (typeof (object)), "#2");
+			Assert.IsTrue (converter.CanConvertTo (typeof (int)), "#3");
 		}
 
 		[Test]
Index: class/System/Test/System.ComponentModel/DoubleConverterTests.cs
===================================================================
--- class/System/Test/System.ComponentModel/DoubleConverterTests.cs	(revision 149643)
+++ class/System/Test/System.ComponentModel/DoubleConverterTests.cs	(working copy)
@@ -41,6 +41,7 @@
 		{
 			Assert.IsTrue (converter.CanConvertTo (typeof (string)), "#1");
 			Assert.IsFalse (converter.CanConvertTo (typeof (object)), "#2");
+			Assert.IsTrue (converter.CanConvertTo (typeof (int)), "#3");
 		}
 
 		[Test]
Index: class/System/Test/System.ComponentModel/Int32ConverterTests.cs
===================================================================
--- class/System/Test/System.ComponentModel/Int32ConverterTests.cs	(revision 149643)
+++ class/System/Test/System.ComponentModel/Int32ConverterTests.cs	(working copy)
@@ -41,6 +41,7 @@
 		{
 			Assert.IsTrue (converter.CanConvertTo (typeof (string)), "#1");
 			Assert.IsFalse (converter.CanConvertTo (typeof (object)), "#2");
+			Assert.IsTrue (converter.CanConvertTo (typeof (int)), "#3");
 		}
 
 		[Test]
Index: class/System/Test/System.ComponentModel/Int16ConverterTests.cs
===================================================================
--- class/System/Test/System.ComponentModel/Int16ConverterTests.cs	(revision 149643)
+++ class/System/Test/System.ComponentModel/Int16ConverterTests.cs	(working copy)
@@ -41,6 +41,7 @@
 		{
 			Assert.IsTrue (converter.CanConvertTo (typeof (string)), "#1");
 			Assert.IsFalse (converter.CanConvertTo (typeof (object)), "#2");
+			Assert.IsTrue (converter.CanConvertTo (typeof (int)), "#3");
 		}
 
 		[Test]
Index: class/System/Test/System.ComponentModel/Int64ConverterTests.cs
===================================================================
--- class/System/Test/System.ComponentModel/Int64ConverterTests.cs	(revision 149643)
+++ class/System/Test/System.ComponentModel/Int64ConverterTests.cs	(working copy)
@@ -41,6 +41,7 @@
 		{
 			Assert.IsTrue (converter.CanConvertTo (typeof (string)), "#1");
 			Assert.IsFalse (converter.CanConvertTo (typeof (object)), "#2");
+			Assert.IsTrue (converter.CanConvertTo (typeof (int)), "#3");
 		}
 
 		[Test]
Index: class/System/Test/System.ComponentModel/ChangeLog
===================================================================
--- class/System/Test/System.ComponentModel/ChangeLog	(revision 149643)
+++ class/System/Test/System.ComponentModel/ChangeLog	(working copy)
@@ -1,3 +1,17 @@
+2010-01-15  Alexandre Gomes  <[email protected]>
+
+	* ByteConverterTests.cs:
+	* DoubleConverterTests.cs:
+	* Int32ConverterTests.cs:
+	* Int16ConverterTests.cs:
+	* Int64ConverterTests.cs:
+	* SingleConverterTests.cs:
+	* UInt32ConverterTests.cs:
+	* SByteConverterTests.cs:
+	* UInt16ConverterTests.cs:
+	* UInt64ConverterTests.cs: Added tests to verify CanConvertTo when
+	targeting primitive types.
+	
 2009-09-29  Alan McGovern  <[email protected]>
 
 	* CategoryAttributeTest.cs: Added new test file.
Index: class/System/Test/System.ComponentModel/SingleConverterTests.cs
===================================================================
--- class/System/Test/System.ComponentModel/SingleConverterTests.cs	(revision 149643)
+++ class/System/Test/System.ComponentModel/SingleConverterTests.cs	(working copy)
@@ -41,6 +41,7 @@
 		{
 			Assert.IsTrue (converter.CanConvertTo (typeof (string)), "#1");
 			Assert.IsFalse (converter.CanConvertTo (typeof (object)), "#2");
+			Assert.IsTrue (converter.CanConvertTo (typeof (int)), "#3");
 		}
 
 		[Test]
Index: class/System/Test/System.ComponentModel/UInt32ConverterTests.cs
===================================================================
--- class/System/Test/System.ComponentModel/UInt32ConverterTests.cs	(revision 149643)
+++ class/System/Test/System.ComponentModel/UInt32ConverterTests.cs	(working copy)
@@ -41,6 +41,7 @@
 		{
 			Assert.IsTrue (converter.CanConvertTo (typeof (string)), "#1");
 			Assert.IsFalse (converter.CanConvertTo (typeof (object)), "#2");
+			Assert.IsTrue (converter.CanConvertTo (typeof (int)), "#3");
 		}
 
 		[Test]
Index: class/System/Test/System.ComponentModel/SByteConverterTests.cs
===================================================================
--- class/System/Test/System.ComponentModel/SByteConverterTests.cs	(revision 149643)
+++ class/System/Test/System.ComponentModel/SByteConverterTests.cs	(working copy)
@@ -41,6 +41,7 @@
 		{
 			Assert.IsTrue (converter.CanConvertTo (typeof (string)), "#1");
 			Assert.IsFalse (converter.CanConvertTo (typeof (object)), "#2");
+			Assert.IsTrue (converter.CanConvertTo (typeof (int)), "#3");
 		}
 
 		[Test]
Index: class/System/Test/System.ComponentModel/UInt16ConverterTests.cs
===================================================================
--- class/System/Test/System.ComponentModel/UInt16ConverterTests.cs	(revision 149643)
+++ class/System/Test/System.ComponentModel/UInt16ConverterTests.cs	(working copy)
@@ -41,6 +41,7 @@
 		{
 			Assert.IsTrue (converter.CanConvertTo (typeof (string)), "#1");
 			Assert.IsFalse (converter.CanConvertTo (typeof (object)), "#2");
+			Assert.IsTrue (converter.CanConvertTo (typeof (int)), "#3");
 		}
 
 		[Test]
Index: class/System/Test/System.ComponentModel/UInt64ConverterTests.cs
===================================================================
--- class/System/Test/System.ComponentModel/UInt64ConverterTests.cs	(revision 149643)
+++ class/System/Test/System.ComponentModel/UInt64ConverterTests.cs	(working copy)
@@ -41,6 +41,7 @@
 		{
 			Assert.IsTrue (converter.CanConvertTo (typeof (string)), "#1");
 			Assert.IsFalse (converter.CanConvertTo (typeof (object)), "#2");
+			Assert.IsTrue (converter.CanConvertTo (typeof (int)), "#3");
 		}
 
 		[Test]
Index: class/System/System.ComponentModel/ChangeLog
===================================================================
--- class/System/System.ComponentModel/ChangeLog	(revision 149643)
+++ class/System/System.ComponentModel/ChangeLog	(working copy)
@@ -1,3 +1,8 @@
+2010-01-15  Alexandre Gomes  <[email protected]>
+
+	* BaseNumberConverter.cs: Fixed CanConvertTo and ConvertTo when
+	targeting primitive types.
+
 2009-12-08  Marek Habersack  <[email protected]>
 
 	* TypeDescriptor.cs: AddProvider overloads must refresh the
Index: class/System/System.ComponentModel/BaseNumberConverter.cs
===================================================================
--- class/System/System.ComponentModel/BaseNumberConverter.cs	(revision 149643)
+++ class/System/System.ComponentModel/BaseNumberConverter.cs	(working copy)
@@ -48,17 +48,12 @@
 
 		public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
 		{
-			if (sourceType == typeof (string)) 
-				return true;
-			return base.CanConvertFrom (context, sourceType);
+			return sourceType == typeof (string) || base.CanConvertFrom (context, sourceType);
 		}
 
 		public override bool CanConvertTo(ITypeDescriptorContext context, Type t)
 		{
-			if (t == typeof (string))
-				return true;
-
-			return base.CanConvertTo (context, t);
+			return t.IsPrimitive || base.CanConvertTo (context, t);
 		}
 
 		public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
@@ -110,6 +105,9 @@
 			}
 #endif
 
+			if(destinationType.IsPrimitive)
+				return Convert.ChangeType(value, destinationType, culture);
+
 			return base.ConvertTo (context, culture, value, destinationType);
 		}
 
_______________________________________________
Mono-devel-list mailing list
[email protected]
http://lists.ximian.com/mailman/listinfo/mono-devel-list

Reply via email to