2009-05-06 4 views
28

У меня есть функция, которая заполняет массив типа sbyte [], и мне нужно передать этот массив другой функции, которая принимает параметр типа byte [].Как преобразовать sbyte [] в байт [] в C#?

Могу ли я преобразовать его красиво и быстро, не копируя все данные или используя магию unsafe?

+0

просто добавил некоторые пробелы в Q, надеюсь, вы не против: D – inspite

ответ

42

Да, вы можете. Поскольку оба byte и sbyte имеют одинаковое двоичное представление, нет необходимости копировать данные. Просто сделайте бросок в Массив, затем нанесите его на byte[], и этого будет достаточно.

sbyte[] signed = { -2, -1, 0, 1, 2 }; 
byte[] unsigned = (byte[]) (Array)signed; 
+0

Ничего себе, потрясающе! Я не думал об этом. : P –

+4

Довольно часто я получаю тип рассогласования с использованием этого подхода –

+0

Я пробовал это, но это работа. Результаты были вопросительными знаками. Что-то, чего я раньше не видел. Вот код 'sbyte [] txdata = {(0x00 | 0x20), ~ (1 << 6)}; byte [] dss = (byte []) ((Array) txdata); ' –

24

Вам нужно будет скопировать данные (только массивы ссылочного типа являются ковариантными), но мы можем попытаться сделать это эффективно; Buffer.BlockCopy, кажется, работает:

sbyte[] signed = { -2, -1, 0, 1, 2 }; 
    byte[] unsigned = new byte[signed.Length]; 
    Buffer.BlockCopy(signed, 0, unsigned, 0, signed.Length); 

Если бы это была ссылка типа, вы можете просто бросить ссылку без дублирования массива:

Foo[] arr = { new Foo(), new Foo() }; 
    IFoo[] iarr = (IFoo[])arr; 
    Console.WriteLine(ReferenceEquals(arr, iarr)); // true 
+0

Угу ... но прочитать последнее предложение вопроса. ;) –

+0

Отредактировано включить примечание о ковариации –

+0

Действительно ??? Вы предоставляете ответ, включив «ссылочные типы массивов ковариант»? Пойдем, по крайней мере, старайтесь быть полезными без самодовольного семантического блеска. – BoiseBaked

6

Если вы используете .NET 3.5+, вы можете использовать следующие:

byte[] dest = Array.ConvertAll(sbyteArray, (a) => (byte)a); 

Который, я думаю, эффективно копирует все данные.

Обратите внимание, что эта функция также находится в .NET 2.0, но вместо этого вам придется использовать анонимный метод.

+0

Ugh. Я предпочел бы использовать Buffer.BlockCopy(). Это, по крайней мере, слепо копирует кучу байтов. У этого есть вызов функции для каждого из них. Кошмар. –

+1

Ну, все зависит от того, сколько вы копируете, но да, блочная копия имеет больше смысла. В конце, если вы хотите, чтобы тип безопасности, единственный способ скопировать. Если вы хотите преобразовать (перебросить) массив, небезопасным будет единственный путь. – Clinton

+0

LOL! Или вы можете сделать то же самое без накладных расходов: byte [] foo = (byte []) (Array), подписанный; – BoiseBaked

Смежные вопросы