【问题标题】:How to convert a sbyte[] to byte[] in C#?如何在 C# 中将 sbyte[] 转换为 byte[]?
【发布时间】:2009-05-06 14:48:21
【问题描述】:

我有一个填充 sbyte[] 类型数组的函数,我需要将此数组传递给另一个接受 byte[] 类型参数的函数。

我可以在不复制所有数据或使用unsafe 魔术的情况下快速快速地转换它吗?

【问题讨论】:

  • 刚刚在 Q 中添加了一些空格,希望你不介意 :D

标签: c# arrays


【解决方案1】:

是的,你可以。 由于bytesbyte 具有相同的二进制表示,因此无需复制数据。 只需对 Array 进行强制转换,然后将其强制转换为 byte[] 就足够了。

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

【讨论】:

  • 哇,太棒了!我没有想到这一点。 :P
  • 我经常使用这种方法收到不匹配的数组类型
  • 调试器(可视化器)似乎对“转换”数组有问题,但它仍然可以正常工作:) +1
  • 这样做是改变数组的编译时类型。有用的技术,但这取决于最终消耗结果的内容。例如, System.Array.Copy(Array, int, Array, int, int) 查看两个数组的 runtime-type ,如果您尝试复制“真实”数组,则会抛出异常byte[]sbyte[] 伪装成 byte[]
  • 我收到“无法将类型 'sbyte[]' 转换为 'byte[]'”的错误
【解决方案2】:

您将不得不复制数据(只有引用类型的数组是协变的)——但我们可以尝试有效地完成它; 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

【讨论】:

  • 已编辑以包含有关协方差的注释
  • @BoiseBaked 我通过说他们需要复制数据并展示一种有效的方法来提供答案,也就是“乐于助人”。数组协方差的上下文是相关的:在其他几乎相同的场景中,不需要复制。如果您的反对意见是使用特定术语:克服它。这是一个概念复杂的技术领域。使用正确的术语可以避免很多混乱。这不是“自我满足”,所以请从那匹高马上爬下来。
【解决方案3】:

如果您使用的是 .NET 3.5+,则可以使用以下内容:

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

也就是说,我猜想有效地复制所有数据。

请注意,此函数也在 .NET 2.0 中,但您必须改用匿名方法。

【讨论】:

  • 呃。那我宁愿使用 Buffer.BlockCopy() 。这至少会盲目地复制一堆字节。这个对它们中的每一个都有一个函数调用。性能噩梦。
  • 嗯,这完全取决于你复制了多少,但是,块复制更有意义。最后,如果你想要类型安全,唯一的方法就是复制。如果你想转换(重铸)数组,不安全是唯一的方法。
  • 哈哈!或者您可以在没有开销的情况下做同样的事情: byte[] foo = (byte[])(Array)signed;
  • @BoiseBaked 不,你不能。这不会改变数组的运行时(元素)类型。
猜你喜欢
  • 1970-01-01
  • 2023-01-24
  • 2018-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-05
  • 2015-08-21
  • 1970-01-01
相关资源
最近更新 更多