Защо се изисква каст за изваждане на байт в C#?

Трябва да следвам кода във 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 е тип цяло число... тогава защо трябва да имам каста?


person Billy    schedule 29.05.2009    source източник
comment
Ерик Липърт казва, че не мисля за байтовете като за числа; Мисля за тях като за шаблони от битове, които могат да бъдат тълкувани като числа, или знаци, или цветове, или каквото и да било. Ако ще правите математика върху тях и ще ги третирате като числа, тогава има смисъл да преместите резултата в тип данни, който по-често се тълкува като число. Вижте stackoverflow.com/questions/941584/byte-byte-int-why-c .   -  person Brian    schedule 03.06.2009
comment
Вие, момчета, осъзнавате ли, че сте маркирали това като дубликат, въпреки че е било зададено преди връзката вече има отговор тук?   -  person Charlie Martin    schedule 27.11.2013
comment
По дяволите, сега дори пише зададен преди, въпреки че другият въпрос е зададен три години по-късно.   -  person Charlie Martin    schedule 18.09.2015
comment
Всъщност всяка стойност на данните е битов модел, който може да се интерпретира като число.   -  person Charlie Martin    schedule 18.09.2015


Отговори (9)


Тъй като изваждането е принуждаване до цяло число. Доколкото си спомням, байтът е неподписан тип в C#, така че изваждането може да ви изведе извън домейна на байтовете.

person Charlie Martin    schedule 29.05.2009
comment
Изваждането може да ви извади от домейна на всеки тип число. Това всъщност не обяснява защо няма специфичен за байта оператор за изваждане. - person John Gietzen; 18.09.2015
comment
Е, тогава отговорът е, защото разработчиците на C# са решили, че не искат такъв. - person Charlie Martin; 18.09.2015

Това е така, защото резултатът от изваждане на байт не се побира в байт:

byte - byte = (0..255) - (0..255) = -255..255
person schnaader    schedule 29.05.2009
comment
Какво хубаво графично обяснение!!! - person Jhonny D. Cano -Leftware-; 29.05.2009
comment
Нито който и да е тип цели числа, освен числа с плаваща запетая или десетични знаци. int също е с краен диапазон, така че (min_int - max_int) няма да пасне, но връща int. - person Adam Frisby; 29.05.2009
comment
@Adam: 1) числата с плаваща запетая и десетичните знаци не са цели числа. 2) Резултатите от изваждането за тях също може да не са подходящи, тъй като те също имат краен (макар и голям) диапазон. - person Brian; 03.06.2009

Аритметика на байтове води до int стойност по подразбиране .

person Timothy Carter    schedule 29.05.2009
comment
Линкът е мъртъв... - person Chiel ten Brinke; 10.10.2017
comment
@Timothy Cartner, отговори само с връзка не се препоръчват на SO, поради причината, поради която стои вече една година, с повредена връзка. Бихте ли предоставили някакъв контекст? - person Rafael Herscovici; 07.08.2018

Тъй като аритметиката на байтове връща цели числа по подразбиране, така че от двете възможни присвоявания по-тесният тип нула (байт) се повишава до int (този на oColor.r - процент). Така типът на операцията е int. Компилаторът няма да ви позволи без преобразуване да присвоите по-широк тип на по-тесен тип, защото това е операция със загуби. Следователно получавате грешката, освен ако изрично не кажете „Знам, че губя някои данни, всичко е наред“ с предаването.

person Adam Wright    schedule 29.05.2009

Това е така, защото изваждането byte връща int. Всъщност всички двоични аритметични операции върху bytes ще върнат int, така че преобразуването е задължително.

person Andrew Hare    schedule 29.05.2009
comment
Мисля, че това е изваждане, всъщност... - person Charlie Martin; 29.05.2009
comment
Ами сега - благодаря, Чарли, коригирах го. - person Andrew Hare; 29.05.2009
comment
Има ли причина за отрицателния вот? - person Andrew Hare; 29.05.2009
comment
Поне не бях аз. Мисля, че имаме случаен отрицателен глас, и аз имам такъв. - person Charlie Martin; 29.05.2009

Тъй като аритметичните операции върху sbyte, byte, ushort и short се преобразуват автоматично в int. Най-правдоподобната причина за това е, че такива операции вероятно ще препълнят или препълнят.

Така във вашата троична операция крайният oColor.R - процент всъщност води до int, а не байт. Така че типът връщане на операцията е int.

person PeterAllenWebb    schedule 29.05.2009

Тъй като аритметичният израз от дясната страна на оператора за присвояване се оценява на int по подразбиране. Във вашия пример percent по подразбиране е int. Можете да прочетете повече за това на страницата на MSDN.

person Alexander Kahoun    schedule 29.05.2009

Опитайте да стартирате този C# код: object o = (byte)(1); o = (int)o; Какво очакваш? сега пробвай :)

Мисля, че това е правилно:

Ерик Липърт казва: „Не мисля за байтовете като за „числа“; ​​мисля за тях като модели от битове, които могат да бъдат интерпретирани като числа, или знаци, или цветове, или каквото и да било. Ако смятате да правите математика на и да ги третираме като числа, тогава има смисъл да преместим резултата в тип данни, който по-често се интерпретира като число."

Може би байтът е по-близо до char, отколкото до int.

person Community    schedule 04.07.2009
comment
Можете да използвате същата логика за short, int и long. Те също са низове от битове, които могат да се интерпретират като числа. - person David Klempfner; 21.05.2018
comment
Опитайте се да кажете това на някой, който помни 8 битови компютри. С изключение на sbyte, няма 8-битова структура, която да се тълкува по-често като число от байт. - person Paul Childs; 23.02.2021

FWIW, java също насърчава байтове към int.

person Licky Lindsay    schedule 02.06.2009