Почему для вычитания байта в С# требуется кастинг?

Мне нужно выполнить следующий код в VS2008.net 3.5 с помощью WinForms:

byte percent = 70;
byte zero = 0;

Bitmap copy = (Bitmap)image1.Clone();
...

Color oColor = copy.GetPixel(x, y);
byte oR = (byte)(oColor.R - percent < zero ? zero : oColor.R - percent);

Когда я оставляю " (byte)" в последней строке кода, я получаю сообщение об ошибке компилятора: "Невозможно неявно преобразовать тип" int "в" byte "." Если все имеет тип byte, а byte - целочисленный тип... тогда зачем мне иметь листинг?

Ответ 1

Потому что вычитание подтягивается до целого числа. Насколько я помню, байт является неподписанным типом в С#, поэтому вычитание может вывести вас из области байтов.

Ответ 2

Это потому, что результат вычитания байта не соответствует байту:

byte - byte = (0..255) - (0..255) = -255..255

Ответ 4

Поскольку арифметика по байтам возвращает целые числа по умолчанию, поэтому из двух возможных назначений более узкий тип нуля (байт) продвигается до int (от oColor.r - процентов). Таким образом, тип операции - это int. Компилятор не будет, без броска, позволит вам назначить более широкий тип более узкому типу, поскольку это операция с потерями. Следовательно, вы получаете ошибку, если вы явно не говорите: "Я знаю, что теряю некоторые данные, это прекрасно" с литой.

Ответ 5

Это потому, что вычитание byte возвращает int. На самом деле любые двоичные арифметические операции на bytes возвращают int, поэтому требуется листинг.

Ответ 6

Поскольку арифметические операции по sbyte, byte, ushort и short автоматически преобразуются в int. Наиболее правдоподобной причиной этого является то, что такие операции, вероятно, переполняются или переполняются.

Таким образом, в вашей тройной операции окончательный oColor.R - процент, фактически приводит к int, а не байту. Таким образом, возвращаемый тип операции - int.

Ответ 7

Поскольку арифметическое выражение в правой части оператора присваивания по умолчанию принимает значение int. В вашем примере percent по умолчанию используется int. Подробнее об этом можно узнать на странице MSDN.

Ответ 8

Попробуйте запустить этот код С#:  объект o = (байт) (1);  o = (int) o; Что вы ожидаете? Теперь попробуйте:)

Я думаю, что это правильно:

Эрик Липперт говорит: "Я не думаю о байтах как" числа ", я думаю о них как о битах, которые могут быть интерпретированы как числа или символы, или цвета или что-то еще. Если вы собираетесь делая математику на них и рассматривая их как числа, тогда имеет смысл перемещать результат в тип данных, который чаще интерпретируется как число".

Возможно, байт ближе к char, чем к int.

Ответ 9

FWIW, java также продвигает байты в int.