Question

Bonjour, j'ai un DataRow extrait d'un DataTable d'un DataSet. J'accède à une colonne définie dans SQL en tant que type de données float. J'essaie d'assigner cette valeur à une variable locale (type de données c # float), mais j'obtiens un InvalidCastExecption

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

Maintenant, en jouant avec cela, j’ai fait en sorte que cela fonctionne, mais cela n’avait aucun sens et cela ne me semblait pas juste.

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

Quelqu'un peut-il expliquer ce qui me manque ici?

Était-ce utile?

La solution

Un float SQL est un double selon la la documentation. pour SQLDbType .

Autres conseils

Un flottant dans SQL est un double dans le CLR. (C # / VB). Il existe une table des types de données SQL avec les équivalents CLR sur MSDN.

Et, normalement, vous ne voudrez jamais utiliser float dans SQL Server (ou réel) si vous prévoyez d'effectuer des calculs mathématiques sur les données, car il s'agit d'un type de données inexact et cela entraînera des erreurs de calcul. Utilisez plutôt un type de données décimal si vous avez besoin de précision.

Le flottant dans Microsoft SQL Server équivaut à un double en C #. La raison en est qu’un nombre à virgule flottante ne peut qu’approcher un nombre décimal, la précision d’un nombre à virgule flottante détermine la précision avec laquelle ce nombre se rapproche d’un nombre décimal. Le type Double représente un nombre à virgule flottante double précision de 64 bits avec des valeurs allant de négatif 1,79769313486232e308 à 1,79769313486232e308 positif, ainsi que des valeurs zéro ou positif, PositiveInfinity, NegativeInfinity et Not-a-Number (NaN).

Je pense que la question principale a été résolue ici mais je me sens obligé d'ajouter quelque chose à la section de la question qui dit que cela fonctionne.

  

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

La raison pour laquelle cela " fonctionne " et la raison pour laquelle il "ne se sent pas bien" c’est que vous rétrogradez le double en float par la deuxième conversion (celle de gauche), de sorte que vous perdez en précision et que vous dites effectivement au compilateur qu’il est correct de tronquer la valeur renvoyée.

En mots, cette ligne indique ... Obtenir un objet (dans ce cas, il s'agit d'un double) Transforme l'objet en un double (perd tout le wrapping) Transformez le double en float (en perdant toute la précision d'un double)

par exemple. Si la valeur est dite 0.0124022806089461 et vous faites ce qui précède alors la valeur de AccelLimit sera 0,01240228

car c’est l’étendue de ce qu’un float dans c # peut obtenir de la valeur double. C’est une chose dangereuse à faire et je suis à peu près sûr que c’est aussi une troncature plutôt que des arrondis, mais quelqu'un voudra peut-être confirmer cela, car je ne suis pas sûr.

La raison pour laquelle il "ne se sent pas bien" C'est parce que C # utilise la même syntaxe pour unboxing et pour casting , qui sont deux choses très différentes. exercise [" DefaultAccelLimit "] contient une double valeur, encadrée en tant qu'objet. (double) est requis pour déballer l'objet dans un double. Le (float) situé devant celui-ci, puis convertit le double en une valeur float. C # n'autorisant pas la boxe et le casting dans la même opération, vous devez donc déballer, puis lancer.

La même chose est vraie même si le casting est non destructif. Si un float était encadré en tant qu'objet que vous vouliez transformer en double, procédez comme suit: (double) (float) object_var .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top