C# - различаются ли байтовые представления разных типов?
Я знаю, что вопрос немного странный, я спрашиваю из чистого любопытства, поскольку я не мог найти какую-либо соответствующую информацию вокруг. Кроме того, пожалуйста, не стесняйтесь редактировать заголовок, я знаю, что это ужасно, но не может быть лучше.
Допустим, у меня есть переменная foo типа object, которая является короткой или короткой. Мне нужно отправить его по сети, поэтому я использую BitConverter для преобразования его в байт []:
byte[] b = new byte[2];
if(foo is short){
BitConverter.GetBytes((short)foo, 0);
}else{
BitConverter.GetBytes((ushort)foo, 0);
}
Волшебство сети / сокета происходит, я хочу вернуть мою переменную. Я знаю тип, который ожидаю получить, поэтому я правильно вызываю BitConverter.GetUInt16 или GetInt16.
Теперь вопрос: действительно ли это важно, как я сериализовал переменную? Я имею в виду, биты одинаковы, так что это не должно иметь никакого значения, я прав? Чтобы я мог
BitConverter.GetBytes((short)foo, 0);
а затем сделать
BitConverter.GetUInt16(myByteArray, 0);
Кто-нибудь?
2 ответа
Чтобы сериализовать вашу переменную, вы должны присвоить результат BitConverter.GetBytes() вашему байту []. Не имеет значения, является ли ваша переменная короткой или короткой, поскольку они имеют одинаковый размер и содержат одинаковые значения в диапазоне от 0 до 32767. Пока размер в порядке, проблем не должно быть.
Таким образом, вы можете сделать свой код так просто:
byte[] b;
if(foo is short || foo is ushort)
b = BitConverter.GetBytes((short)foo); // You get proper results for ushort as well
Однако на сайте декодирования вы должны знать, какой тип вам нужен, для краткости, вам нужно:
short foo = BitConverter.ToInt16(b, 0);
но если вам нужен ushort, то вы пишете:
ushort foo = BitConverter.ToUInt16(b, 0);
Когда вы отправляете многобайтовые переменные по сети, вы также должны убедиться, что они имеют сетевой порядок байтов, как @itsme86, упомянутое в его ответе.
Если вам нужно отправить как короткие, так и короткие, то вам также необходимо отправить информацию о типе на другой конец, чтобы узнать, подписан ли тип данных или нет. Я не пишу об этом сейчас подробно, так как это усложнит код.
Если вы передаете его по сети, у вас могут возникнуть проблемы с порядком байтов (т. Е. Многобайтовые значения могут храниться в разном порядке байтов на разных архитектурах). Стандартное соглашение при отправке многобайтового значения по сети - преобразовать его в сетевой порядок байтов.
Получатель многобайтового значения затем преобразует его в Порядок байтов хоста.