Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeConverters broken for primitive types?

I'm running into an issue with the DecimalConverter and Int32Converter classes, which seem to be returning inconsistent results, as demonstrated by the following simple console program:

using System;
using System.ComponentModel;

class App
{
    static void Main()
    {
        var decConverter = TypeDescriptor.GetConverter(typeof(decimal));
        Console.WriteLine("Converter: {0}", decConverter.GetType().FullName);
        Console.WriteLine("CanConvert from int to decimal: {0}", decConverter.CanConvertFrom(typeof(int)));
        Console.WriteLine("CanConvert to int from decimal: {0}", decConverter.CanConvertTo(typeof(int)));

        Console.WriteLine();

        var intConverter =  TypeDescriptor.GetConverter(typeof(int));
        Console.WriteLine("Converter: {0}", intConverter.GetType().FullName);
        Console.WriteLine("CanConvert from int to decimal: {0}", intConverter.CanConvertTo(typeof(decimal)));
        Console.WriteLine("CanConvert to int from decimal: {0}", intConverter.CanConvertFrom(typeof(decimal)));
    }
}

The output from this is as follows:

Converter: System.ComponentModel.DecimalConverter
CanConvert from int to decimal: False
CanConvert to int from decimal: True

Converter: System.ComponentModel.Int32Converter
CanConvert from int to decimal: False
CanConvert to int from decimal: False

Unless I'm understanding TypeConverters incorrectly, the following should hold true:

TypeDescriptor.GetConverter(typeof(TypeA)).CanConvertFrom(typeof(TypeB))

should give the same result as

TypeDescriptor.GetConverter(typeof(TypeB)).CanConvertTo(typeof(TypeA))

At least in the case of System.Int32 and System.Decimal, they do not.

My question is this: Does anybody know if this is by design? Or are the TypeConverters for native types in C# actually broken?

like image 979
rossipedia Avatar asked May 07 '12 22:05

rossipedia


2 Answers

According to the MSDN documentation for Int32Converter...

This converter can only convert a 32-bit signed integer object to and from a string.

I agree with @svick in the comments, though, I'm not understanding why you would need to deserialize a JSON string through Int32 to a Decimal in the first place.

like image 192
Chris Hannon Avatar answered Nov 14 '22 14:11

Chris Hannon


You shouldn't need to deal with type converters in cases like this at all. If you want to deserialize your model class, do something like:

serializer.Deserialize<Model>(json)

And it will take care of all conversions for you.

If you actually need to do the conversion manually, use Convert.ToDecimal(integer) (or Convert.ChangeType(integer, typeof(decimal))) and it will work correctly.

like image 27
svick Avatar answered Nov 14 '22 14:11

svick