C# 将字节[]转换为sbyte[]

C# 将字节[]转换为sbyte[],c#,type-conversion,C#,Type Conversion,我试图将数组从byte[]转换为sbyte[] 以下是我的示例阵列: byte[] unsigned = { 0x00, 0xFF, 0x1F, 0x8F, 0x80 }; 我已经试过了: sbyte[] signed = (sbyte[])((Array)unsigned); 但它不起作用。执行此操作后,数组中没有值 有人有更好的主意吗?很容易做到这一点: sbyte[] signed = unsigned.Select(b=>(sbyte)b).ToArray(); 我对语法没有

我试图将数组从
byte[]
转换为
sbyte[]

以下是我的示例阵列:

byte[] unsigned = { 0x00, 0xFF, 0x1F, 0x8F, 0x80 };
我已经试过了:

sbyte[] signed = (sbyte[])((Array)unsigned);
但它不起作用。执行此操作后,数组中没有值

有人有更好的主意吗?

很容易做到这一点:

sbyte[] signed = unsigned.Select(b=>(sbyte)b).ToArray();
我对语法没有把握。核实一下

sbyte[] signed = (sbyte[]) (Array) unsigned;
这是因为byte和sbyte在内存中具有相同的长度,可以在不改变内存表示的情况下进行转换

但是,此方法可能会导致调试器出现一些奇怪的错误。如果字节数组不是很大,可以使用
array.ConvertAll

sbyte[] signed = Array.ConvertAll(unsigned, b => unchecked((sbyte)b));
使用如何?这个答案的好处是避免了逐字节的强制转换检查。这个答案的缺点是避免了逐字节的强制转换检查

var unsigned = new byte[] { 0x00, 0xFF, 0x1F, 0x8F, 0x80 };
var signed = new sbyte[unsigned.Length];
Buffer.BlockCopy(unsigned, 0, signed, 0, unsigned.Length);
这只是复制字节,高于
byte的值。MaxValue
将具有负
sbyte


需要两行代码,但应该很快。

旧.net framework和旧.net core不支持重新解释转换,但支持*指针和不安全代码。 新的.net版本添加system.memory库,可以解决此问题并复制内存

   byte[] unsigned = { 0x00, 0xFF, 0x1F, 0x8F, 0x80 };  
   ReadOnlySpan<byte> bytesBuffer = unsigned;
   ReadOnlySpan<sbyte> sbytesBuffer = MemoryMarshal.Cast<byte, sbyte>(bytesBuffer);
   sbyte[] signed = sbytesBuffer.ToArray();
byte[]unsigned={0x00,0xFF,0x1F,0x8F,0x80};
ReadOnlySpan bytesBuffer=无符号;
ReadOnlySpan sbytesBuffer=MemoryMarshal.Cast(bytesBuffer);
sbyte[]signed=sbytesBuffer.ToArray();

此代码的工作原理是编译并不会抛出错误。它产生一个数组,几乎在任何情况下都可以用作
sbyte[]
,但运行时仍将其标记为
byte[]
。不确定“数组中没有值”是什么意思,对我来说,数组是
{0,-1,31,-113,-128}
。编译后,签名数组中没有值。Visual Studio在签名数组的每个元素中显示“?”。好的,我尝试从签名数组中获取一个元素,但它仍然有效。谢谢你的帮助。我尝试使用这个解决方案。那就是VS限制。VS可能不理解静态类型为
sbyte[]
而动态类型为
byte[]
的数组是有效的。CLR允许此强制转换,但C#不允许。这是一种黑客行为,因此在大多数应用程序中,您都希望使用@Selman的建议。只是调试器在显示它时有问题,因为它实际上是
sbyte[]
byte[]
的引用。我会使用
未选中((sbyte)b)
,因此即使启用了选中的算术,它也会工作。它还作为文档说明溢出是有意的,而不仅仅是性能优化。我的内存告诉我溢出检查不适用于字节/字节。我可能错了。编辑:现在修复:)将255投射到
sbyte
肯定会使用选中的算法抛出。可能会让您感到困惑的是,
(byte)255+(byte)255
不会抛出,因为操作数会被提升到
int
而不会溢出。我可能会以任何方式修复它。谢谢你指出:)不需要
@
signed
/
unsigned
不是C#中的关键字。@CodesInChaos让我误入歧途。这很有效。但是1)
ConvertAll
更快,可读性也一样2)我更喜欢
unchecked((sbyte)b)
。有关详细信息,请参见@sepher的答案。