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的答案。