2012-05-07 24 views
8

estoy corriendo en un problema con los DecimalConverter y Int32Converter clases, que parecen estar volviendo resultados inconsistentes, como lo demuestra el siguiente programa de consola sencilla:TypeConverters roto para tipos primitivos?

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))); 
    } 
} 

El resultado de esto es la siguiente:

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 

A menos que yo estoy entendiendo TypeConverters incorrectamente, el siguiente debe ser cierto:

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

debe dar el mismo resultado que

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

Al menos en el caso de System.Int32 y System.Decimal, no lo hacen.

Mi pregunta es esta: ¿Alguien sabe si esto es por diseño? ¿O están realmente rotos los TypeConverters para los tipos nativos en C#?

+2

No entiendo por qué necesita convertir 'int' a' decimal' al deserializar JSON, ya que JSON contiene cadenas, no 'int's. – svick

+0

He ampliado mi pregunta para aclarar. Me di cuenta de que probablemente podría manejar esto asegurándome de serializar todo como una cadena en su camino hacia el navegador, pero esa no es realmente la pregunta, más un preludio. – rossipedia

Respuesta

2

De acuerdo con la MSDN documentation para Int32Converter ...

Este convertidor sólo puede convertir un objeto firmado entero de 32 bits y de de una cadena.

Estoy de acuerdo con @svick en los comentarios, sin embargo, no entiendo por qué tendrías que deserializar una cadena JSON a través de Int32 a un decimal en primer lugar.

+0

Yo no. El manejo JSON predeterminado de ASP.NET MVC sí lo hace. Al enviar una solicitud 'application/json' a través de AJAX, el' JavaScriptSerializer' predeterminado deserializará todos los números enteros como objetos Int32. Tengo problemas cuando el sistema intenta volver a asignar esos valores Int32 a una propiedad 'decimal' de mi Modelo. – rossipedia

+2

@BryanRoss ¿Has visto [esta pregunta de StackOverflow?] (Http://stackoverflow.com/questions/8964646/javascriptserializer-and-asp-net-mvc-model-binding-yield-different-results) Sospecho que es bastante similar a su problema, ya que necesita pasar sus decimales como cadenas entre comillas. El 'JavaScriptSerializer' adivinará el tipo incorrectamente y terminará probando conversiones inapropiadas basadas en su mala suposición, pero al citar explícitamente los valores se probará una cadena para escribir la conversión, que debería ser una solución más viable. –

+0

Gracias Chris, definitivamente estoy de acuerdo contigo, y de hecho ya he llegado a esta solución. Todavía me gustaría saber por qué TypeConverter no informa capacidades consistentes. – rossipedia

1

No debería tener que tratar con convertidores de tipo en casos como este en absoluto. Si desea deserializar la clase del modelo, hacer algo como:

serializer.Deserialize<Model>(json) 

Y se hará cargo de todas las conversiones para usted.

Si realmente necesita hacer la conversión manualmente, use Convert.ToDecimal(integer) (o Convert.ChangeType(integer, typeof(decimal))) y funcionará correctamente.

+0

No es mi código el que está usando TypeConverters. Es ASP.NET MVC's. Sin embargo, la pregunta es sobre TypeConverters y por qué producen resultados inconsistentes, no serialización/deserialización de JSON. – rossipedia

+0

Entonces tal vez esa no es la pregunta que debería hacerse. Creo que estás haciendo algo mal con respecto a la deserialización de JSON, no es culpa de los convertidores de tipo. – svick

+1

El programa de ejemplo que publiqué no tiene nada que ver con json, pero muestra el comportamiento que describí y sobre el que pregunté. Y como he indicado antes, mi código no está realizando la deserialización. Es el código de ASP.NET MVC que es. Un valor numérico no incluido en la solicitud JSON no se puede asignar a una propiedad decimal de forma automática, debido al problema real sobre el que pregunté. No estoy tratando de ser grosero aquí, soy plenamente consciente de cómo solucionar mi problema JSON en particular. No es un problema. Estoy preguntando muy específicamente sobre el comportamiento de TypeConverters con respecto a los tipos numéricos nativos. – rossipedia

Cuestiones relacionadas