6
votes

Pourquoi C # jetez des erreurs de casting lors de la tentative d'opérations mathématiques sur des types entier autres que INT?

Considérez cette classe d'essai statique: xxx

Ceci provoque l'erreur de compilation suivante, avec value1 + value2 souligné en rouge:

ne peut pas convertir implicitement le type 'int' à 'Ushort'. Une conversion explicite existe (vous manquez-vous un casting)?

pourquoi?


3 commentaires

Le compilateur vous demande d'être explicite sur le fait que vous faites une conversion de rétrécissement, où les données peuvent être perdues. Si vous passez à Ushort.MaxValue et 1, que devriez-vous arriver? C'est la question que le compilateur vous rappelle de répondre.


@Dan: Que devrait-il arriver est le Ushort devrait déborder automatiquement ou lancer une exception de trop-plein si le mot clé coché est utilisé. Si vous ajoutez deux valeurs int , vous n'obtenez pas la même erreur de compilateur, même si le débordement est possible.


Ma prise: Le débordement est quelque chose qui se produit à la suite d'une opération, pas une mission. En particulier, vous pouvez déborder au milieu d'un calcul complexe, même si le résultat final serait dans la gamme. Si un débordement survient, les mathématiques n'ont pas réussi à fonctionner comme prévu, mais cela ne se produit pas lors de l'ajout de deux ushorts sur un système 32 bits. Les maths ont fonctionné bien, mais vous devez maintenant décider comment interpréter le résultat. Si vous voulez dépasser USHORT, vous pouvez la jeter explicitement à un Ushort. Cela pourrait se produire implicitement, mais nécessitant une fonte explicite est utile.


4 Réponses :


7
votes

Comme C et C ++ avant cela, les entiers sont implicitement élargis lorsqu'ils sont utilisés avec de nombreux opérateurs. Dans ce cas, le résultat de l'ajout de deux valeurs Ushort est int .

mise à jour:

Plus d'informations: http: // msdn .microsoft.com / fr-US / US / Bibliothèque / AA691330 (v = vs.71) .aspx

Je pense que cela a été ajouté à l'origine en C / C ++ car int était un type d'entier natif (et oui, les opérations étaient plus rapides sur int S que sur S sur des architectures 32 bits). Je ne suis pas sûr de la justification complète de c #.

Il vous fait penser aux considérations de débordement / troncature lorsque vous lancez. Le débordement accidentel est plus probable avec les plus petits types entier.


5 commentaires

C'est donc fait de cette façon parce que ça a toujours été fait de cette façon?


Étant donné que les conversions doivent exister quand même, il est plus facile de se convertir en un seul type et d'appliquer les opérateurs que de mettre en œuvre les opérateurs séparément pour chaque type sur les conversions qui existent déjà.


Cela, et la machine est implicitement arithmétique comme "INT". En outre, s'il y a beaucoup de conversions implicites, il devient beaucoup plus probable que le compilateur choisisse une conversion que vous n'avez pas vraiment l'intention. (Voir PL / I, par exemple.)


Voir la réponse mise à jour. Je crois que le commentaire d'Eric sur l'arithmétique de la machine virtuelle est la raison la plus probable pour laquelle cela reste fait aujourd'hui.


@ROBERT: "Sinon, les deux opérandes sont converties en type int ." Cela s'appliquerait à deux Ushort .



5
votes

Ushort

La déclaration d'affectation suivante produira une erreur de compilation, parce que l'expression arithmétique sur le côté droit de l'affectation L'opérateur évalue par défaut par défaut. xxx

Pour résoudre ce problème, utilisez un casting: xxx


0 commentaires

2
votes

Les opérateurs d'addition disponibles en C # n'envisagent que int code>, uint code>, long code> et ulong code> types de données Ce cas, vous posez implicitement deux Ushort code> sur int code>, puis exécutant l'addition, puis renvoyant un int code> qui ne peut pas être implicitement déposé sur Ushort code>.

de la spécification C # 4.0, section 7.8.4 Opérateur d'addition em>, vous pouvez vérifier que seuls les opérateurs d'addition entier suivants sont disponibles: P>

int operator +(int x, int y);
uint operator +(uint x, uint y);
long operator +(long x, long y);
ulong operator +(ulong x, ulong y);


0 commentaires

1
votes

C'est parce que l'addition ou la soustraction de Ushorts ne donnent pas nécessairement à un UShort. Par exemple, le résultat pourrait être <0, qui n'est pas un Ushort. Donc, vous devez donner au compilateur la pointe de ne pas vous plaindre par type de jumelage. Je crois que cela devrait fonctionner: retour (Ushort) (valeur1 + valeur2);


0 commentaires