【发布时间】:2019-08-04 09:36:19
【问题描述】:
我希望得到一个 Span 代表的原始值。以下面的代码为例,我如何在DoWork 中访问原始字节数组而不创建它的副本?
static void Main()
{
var data = new byte[0x100];
DoWork(new Span<byte>(data));
}
private void DoWork(Span<byte> Data)
{
//var data = Data.ToArray(); Unsuitable; creates a copy
//var data = (byte[])Data; Unsuitable; doesn't work
//MemoryMarshal. Something in here may work, but unsure
//MemoryExtensions. Something in here may work, but unsure
}
我发现 2 个带有辅助方法的静态类(如上所示)可能会有所帮助,但我不确定在不让事情变得比制作副本更慢的情况下最好的方法是什么。
【问题讨论】:
-
跨度是原始值上的一个窗口,可以将其视为指向该字节的指针。因为您有跨度,所以您可以参考实际值。
Data[i]将为您提供对指定索引的引用或遍历跨度以查看窗口中的所有引用。 -
Span的全部意义在于为您提供原始数据的抽象视图。对于DoWork而言,这将是层违规 1) assumeData由byte[]支持(而不是非托管内存,例如)和 2) 通过封装伸出手来获得在那byte[]。您应该(重新)在DoWork中编写代码以使用Span,这样您就不需要首先获取“原始字节数组”。如果你确实需要它,那么不要传递Span——传递数组!Span什么也得不到,而其他代码仍然只在数组上工作。 -
技术上这是不可能的。跨度包含一个指针,该指针可能指向字节数组的中间。您不能使用该指针并再次找到字节数组的开头。同样,您不能获取该指针并从该指针开始构造一个新数组,而无需复制。
-
不涉及复制。您正在通过该 Span 查看原始值。为什么不直接使用 Span?为什么要从中创建一个数组?
-
感谢大家的澄清。
标签: c# .net system.memory