Pregunta

Hola, tengo un DataRow sacado de un DataTable de un DataSet.Estoy accediendo a una columna que está definida en SQL como un tipo de datos flotante.Estoy intentando asignar ese valor a una variable local (tipo de datos flotante de C#) pero obtengo una InvalidCastExecption

DataRow exercise = _exerciseDataSet.Exercise.FindByExerciseID(65);
_AccelLimit = (float)exercise["DefaultAccelLimit"];  

Ahora, jugando con esto, lo hice funcionar, pero no tenía ningún sentido y no me sentía bien.

_AccelLimit = (float)(double)exercise["DefaultAccelLimit"];

¿Alguien puede explicar lo que me falta aquí?

¿Fue útil?

Solución

Un flotante SQL es un doble según la documentación para SQLDbType.

Otros consejos

Un flotante en SQL es un Doble en el CLR (C#/VB).hay una tabla de tipos de datos SQL con los equivalentes CLR en MSDN.

Y normalmente nunca querrás usar float en SQL Server (o real) si planeas realizar cálculos matemáticos con los datos, ya que es un tipo de datos inexacto e introducirá errores de cálculo.Utilice un tipo de datos decimal en su lugar si necesita precisión.

El flotante en Microsoft SQL Server es equivalente a un Double en C#.La razón de esto es que un número de punto flotante sólo puede aproximarse a un número decimal, el precisión de un número de punto flotante determina con qué precisión ese número se aproxima un número decimal.El tipo Double representa un número de coma flotante de 64 bits de doble precisión con valores que van desde 1.79769313486232e308 negativo hasta 1.79769313486232e308 positivo, así como cero positivo o negativo, PositiveInfinity, NegativeInfinity y Not-a-Number (NaN).

Creo que la pregunta principal ha sido respondida aquí, pero me siento obligado a agregar algo para la sección de la pregunta que dice que esto funciona.

_AccelLimit = (flotante)(doble)ejercicio["DefaultAccelLimit"];

La razón por la que esto "funciona" y la razón por la que "no se siente bien" es que estás degradando el doble a flotante en el segundo lanzamiento (el de la izquierda), por lo que estás perdiendo precisión y efectivamente le estás diciendo al compilador que está bien truncar el valor devuelto.

En palabras, esta línea dice...Obtenga un objeto (que tiene un doble en este caso) coloque el objeto en un doble (perdiendo todo el envoltorio del objeto) coloque el doble en un flotador (perdiendo toda la precisión fina de un doble)

p.ej.Si el valor es, por ejemplo, 0.0124022806089461 y usted hace lo anterior, entonces el valor de acelimit será 0.01240228

ya que ese es el alcance de lo que un flotante en C# puede obtener del valor doble.Es algo peligroso y estoy bastante seguro de que también es un truncamiento en lugar de un redondeo, pero es posible que alguien quiera confirmarlo porque no estoy seguro.

La razón por la que "no se siente bien" es porque C# usa la misma sintaxis para desempaquetar y para fundición, que son dos cosas muy diferentes. exercise["DefaultAccelLimit"] contiene un valor doble, encuadrado como un objeto. (double) se requiere para desembalar el objeto de nuevo en un doble.El (float) frente a eso entonces moldes el doble a un valor flotante.C# no permite encajonar y convertir en la misma operación, por lo que debe desempaquetar y luego convertir.

Lo mismo ocurre incluso si el yeso no es destructivo.Si un flotador estuviera encuadrado como un objeto que desea convertir en un doble, lo haría así: (double)(float)object_var.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top