Ответ 1
Потому что вычитание подтягивается до целого числа. Насколько я помню, байт является неподписанным типом в С#, поэтому вычитание может вывести вас из области байтов.
Мне нужно выполнить следующий код в 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
- целочисленный тип... тогда зачем мне иметь листинг?
Потому что вычитание подтягивается до целого числа. Насколько я помню, байт является неподписанным типом в С#, поэтому вычитание может вывести вас из области байтов.
Это потому, что результат вычитания байта не соответствует байту:
byte - byte = (0..255) - (0..255) = -255..255
Арифметика по байтам приводит к значению int по умолчанию.
Поскольку арифметика по байтам возвращает целые числа по умолчанию, поэтому из двух возможных назначений более узкий тип нуля (байт) продвигается до int (от oColor.r - процентов). Таким образом, тип операции - это int. Компилятор не будет, без броска, позволит вам назначить более широкий тип более узкому типу, поскольку это операция с потерями. Следовательно, вы получаете ошибку, если вы явно не говорите: "Я знаю, что теряю некоторые данные, это прекрасно" с литой.
Это потому, что вычитание byte
возвращает int
. На самом деле любые двоичные арифметические операции на bytes
возвращают int
, поэтому требуется листинг.
Поскольку арифметические операции по sbyte, byte, ushort и short автоматически преобразуются в int. Наиболее правдоподобной причиной этого является то, что такие операции, вероятно, переполняются или переполняются.
Таким образом, в вашей тройной операции окончательный oColor.R - процент, фактически приводит к int, а не байту. Таким образом, возвращаемый тип операции - int.
Поскольку арифметическое выражение в правой части оператора присваивания по умолчанию принимает значение int. В вашем примере percent
по умолчанию используется int
. Подробнее об этом можно узнать на странице MSDN.
Попробуйте запустить этот код С#: объект o = (байт) (1); o = (int) o; Что вы ожидаете? Теперь попробуйте:)
Я думаю, что это правильно:
Эрик Липперт говорит: "Я не думаю о байтах как" числа ", я думаю о них как о битах, которые могут быть интерпретированы как числа или символы, или цвета или что-то еще. Если вы собираетесь делая математику на них и рассматривая их как числа, тогда имеет смысл перемещать результат в тип данных, который чаще интерпретируется как число".
Возможно, байт ближе к char, чем к int.
FWIW, java также продвигает байты в int.