2011-12-08 17 views
5

Prob algo estoy pasando por alto, pero este problema me ha molestado mucho. Estoy tratando de obtener un valor de un conjunto de datos y luego lo uso para hacer algunos cálculos. en el conjunto de datos se ve como un objeto, por lo que tengo que convertirlo en un int o doble. Por alguna razón estoy recibiendo un error estúpido que me está poniendo de los nervios. Aquí está el código.C# error de fundición (valor infinte .... ¿qué?)

private void SpendsAnalysis() 
    { 
     float tempQty = 0; 
     float tempPrice = 0; 
     double tempTot = 0; 
     double total = 0; 

     foreach (DataGridViewRow row in dataGridView1.Rows) 
     { 
      tempQty = (float)row.Cells["Qty"].Value; 
      tempPrice = (float)row.Cells["Unit"].Value; 

      tempTot = tempQty * tempPrice; 
      total += tempTot; 
     } 

     textBox7.Text = total.ToString(); 
    } 

Lanzamiento: "El modelo especificado no es válido." (System.InvalidCastException) al convertir un número, debe ser menor que inifnite. Este es el error molesto que recibo. ahora obtengo los datos de mi conjunto de datos, que obtiene sus datos de un procedimiento almacenado. Creo que el tipo de campo "Cantidad" es la moneda (sí, ¿por qué es qty moneda jaja, no mis tablas!). en mi vista de cuadrícula de datos parece 1,000, ¿esto se debe a una conversión de tipo? ¿Cómo puedo rectificar esto? ¡Muchas gracias de antemano!

+4

'float' es sin duda un partido peor que' 'currency' o decimal '. Pero parece que debería ser un número entero. Cualquier 'flotante'/'doble' que ocurra en un cálculo monetario es una gran bandera roja. – CodesInChaos

+0

de acuerdo, pero estos son valores establecidos por la tabla original. Estoy lanzándolo a un valor con el que puedo trabajar, doble o flotante – lemunk

+0

¿Y por qué no 'Decimal'? Puede usar decimal en C#, y ciertamente es una mejor opción que cualquiera de los modos 'float' o' double' aquí. – CodesInChaos

Respuesta

9

Un tipo fundido tiene que tener éxito, y por desgracia, la fundición directamente desde un object a un tipo diferente que el objeto subyacente no va a funcionar, incluso si la fundición de una (el tipo de .NET para currency) decimal a un float normalmente funcionaría

Si el tipo de la base de datos es currency, me gustaría probar esto:

= (float)(decimal)row.Cells["Qty"].Value; 

o, puede utilizar this:

= Convert.ToSingle(row.Cells["Qty"].Value); 

que echar un vistazo al valor real y figura el tipo correcto de conversión para realizar.

Para responder a su comentario, la expresión anterior implica dos conversiones distintas:

  • Una conversión unboxing de object a un tipo de valor, en este caso a un decimal
  • una conversión explícita de decimal a float

La primera, la conversión de unboxing, está documentada en la sección de especificación del lenguaje C# 4.3.2 (este es el C# 4.0 specification):

Una operación unboxing a un no anulable-valor de tipo consiste en primero la comprobación de que la instancia del objeto es un valor en caja del valor de tipo no anulable dado, y luego copiando el valor fuera de la instancia.

(el subrayado es mío)

que también tienen la versión anotada de la especificación, y Eric Lippert resume esto como:

Aunque es legal para convertir un int sin embalaje a una unboxed double, no es legal convertir un int encuadrado en un unboxed double-only a unboxed int.

La segunda, la conversión explícita, se documenta en la sección C# especificación del lenguaje 6.2.1:

6.2.1 explícita numéricas Conversiones
Las conversiones numéricas explícitas son las conversiones de una tipo numérico a otro tipo numérico para el que no existe una conversión numérica implícita (§6.1.2):
...
De decimal a sbyte, byt e, corto, ushort, int, uint, largo, ulong, char, flotante, o doble.

(de nuevo, mi énfasis)

En resumen:

  • Cuando "casting" de una object a un tipo de valor, en realidad estás unboxing el valor en caja, y primero debe desempaquetar el valor real subyacente en su tipo correcto, antes de poder convertirlo a un tipo diferente.
+0

hmmmmm interesante – lemunk

+0

ah, muchas gracias, el convert.tosingle funciona como un regalo, por lo que el hecho es un objeto que significa que no se puede convertir? ¿hay más información sobre esto? – lemunk

+3

Habiendo dicho todo lo que quería decir en mi respuesta, ¿está seguro de que * quiere * como '' flotante '' y no como 'decimal '? –

Cuestiones relacionadas