web-dev-qa-db-fra.com

Conversion d'octets C # int

Pourquoi est-ce

byte someVar;
someVar -= 3; 

valide mais

byte someVar;
someVar = someVar - 3;

n'est-ce pas?

28
Dested

Étonnamment, lorsque vous effectuez des opérations sur les octets, les calculs seront effectués à l'aide des valeurs int, les octets étant implicitement convertis en (int) premier. Cela est également vrai pour shorts, et de même floats sont convertis en double lors de l'arithmétique à virgule flottante.

Le deuxième extrait équivaut à:

byte someVar;
someVar = (int) someVar - 3;

Pour cette raison, vous devez restituer le résultat sur (byte) pour que le compilateur accepte l'affectation.

someVar = (byte) (someVar - 3);
30
John Kugelman

Voici une copie d'un tableau dans la spécification CLI (Ecma 335) qui spécifie quels opérandes sont valides sur les opérateurs numériques binaires du type A op B, où A et B sont les opérandes et "op" est l'opérateur, comme Opcodes. Sub que vous utilisez dans votre extrait:

alt text

Quelques annotations sont nécessaires avec ceci:

  • "native int" est IntPtr dans un programme C #
  • F représente un type à virgule flottante, double ou flottant en C #
  • & représente une valeur de pointeur, les cases sont grisées car ce sont des opérations dangereuses
  • O représente une référence d'objet
  • x est une opération non autorisée.

Notez la ligne et la colonne pour F , les deux opérandes doivent être à virgule flottante, vous ne pouvez pas ajouter directement, disons, un int à un double. Le compilateur C # gère cette limitation en convertissant automatiquement l'opérande int en double afin que l'opérateur soit valide.

Relatif à votre question: notez également que les types byte, sbyte, char, short et ushort ne sont pas présents. Même approche, le compilateur convertit les opérandes en le plus petit type pouvant représenter la valeur afin que l'opérateur puisse être utilisé. Ce sera int32. Selon le tableau, le résultat de l'opération sera int32.

Maintenant, voici le hic: le résultat est int32 mais attribuer cela à une valeur d'octet nécessite une conversion plus étroite. De 32 bits à 8 bits. C'est un problème car il perd des bits importants. Le compilateur C # vous oblige à le rendre explicite. Vous reconnaissez essentiellement que vous savez ce que vous faites et que vous êtes conscient du résultat potentiellement surprenant. Comme celui-ci:

byte v = 255;
v = (byte)(v + 1);

L'opérateur - = est un problème car il n'existe aucun moyen efficace d'appliquer la conversion requise. Il n'est pas exprimable dans la syntaxe du langage. L'utilisation de (octet) 3 n'a pas de sens, le littéral est de toute façon converti en int32 pour faire fonctionner l'opérateur.

Ils ont lancé le problème, le compilateur émet automatiquement le casting sans votre aide.

11
Hans Passant