Je ne peux pas vous donner la raison, mais je peux dire pourquoi le compilateur a ce comportement du point de vue des règles que le compilateur doit suivre (ce qui n'est peut-être pas ce que vous voulez savoir).
D'une ancienne copie de la spécification C# (je devrais probablement télécharger une version plus récente), l'accent a ajouté:
14.2.6.2 Binary numeric promotions This clause is informative.
Binary numeric promotion occurs for the operands of the predefined +
, ?
, *
, /
, %
, &
, |
, ^
, ==
, !=
, >
, <
, >=
, and <=
binary operators. Binary numeric promotion implicitly converts both operands to a common type which, in case of the non-relational operators, also becomes the result type of the operation. Binary numeric promotion consists of applying the following rules, in the order they appear here:
- If either operand is of type decimal, the other operand is converted to type decimal, or a compile-time error occurs if the other operand is of type float or double.
- Otherwise, if either operand is of type double, the other operand is converted to type double.
- Otherwise, if either operand is of type float, the other operand is converted to type float.
- Otherwise, if either operand is of type ulong, the other operand is converted to type ulong, or a compile-time error occurs if the other operand is of type sbyte, short, int, or long.
- Otherwise, if either operand is of type long, the other operand is converted to type long.
- Otherwise, if either operand is of type uint and the other operand is of type sbyte, short, or int, both operands are converted to type long.
- Otherwise, if either operand is of type uint, the other operand is converted to type uint.
- Otherwise, both operands are converted to type int.
Ainsi, opérandes essentiellement plus petit qu'un int
sera converti en int
pour ces opérateurs (et le résultat sera un int
pour les opérations non relationnelles).J'ai dit que je ne pouvais pas vous donner de raison d'être; Cependant, je vais faire une supposition à un - je pense que les concepteurs de C# voulait s'assurer que les opérations qui pourraient perdre des informations si rétréci aurait besoin d'avoir cette opération de rétrécissement rendue explicite par le programmeur sous la forme d'une distribution. Par exemple:
byte a = 200;
byte b = 100;
byte c = a + b; // value would be truncated
Bien que ce genre de troncature ne se produira pas lors de l'exécution d'une opération XOR entre deux opérandes octet, je pense que les concepteurs de langage ne voulait probablement pas avoir un ensemble de règles plus complexes où certains les opérations nécessiteraient des conversions explicites et d'autres non.
Juste une petite note: la citation ci-dessus est « d'information » et non « normatif », mais il couvre tous les cas dans une forme facile à lire. Au sens strict (dans un sens normatif), la raison pour laquelle l'opérateur ^
se comporte de cette façon est le plus proche parce que la surcharge pour cet opérateur face à des byte
opérandes est (à partir 14.10.1 « opérateurs logiques Integer »):
int operator ^(int x, int y);
Par conséquent, comme l'explique le texte informatif, les opérandes sont promus à int
et un résultat int
est produit.
en effet c'est bizarre, les opérations binaires (bien sauf pour passer à gauche) ne débordent pas – Hao
octets opérations en général peuvent retourner des valeurs supérieures à 255, comme lorsque vous avez quitté déplacer un octet, bien sûr et/ou les opérateurs ne générer des résultats plus gros que des octets mais pour des raisons de compatibilité, le résultat sera int! –