[英]Proper way to get a mutable struct for Memory<byte> / Span<byte>?
[英]Can I get a Span<byte> that references a struct member field of non-byte type?
说我有一个类似下面的结构:
struct MyStruct {
Guid g;
}
是否有可能获得引用该结构字节的Span<byte>
?
struct MyStruct {
Guid g;
public void Foo() {
Span<byte> bytes = ???
}
}
这样, bytes
将是长度为16的Span<byte>
,这将允许直接读取和写入Guid字段的各个字节。
我可以对不安全的代码执行类似的操作,但似乎现在应该可以通过跨度的安全代码来实现,但是我无法弄清楚如何产生跨度。
编辑:澄清一下,我想要一个跨度指向Guid的实际存储位置。 意思是new Span<byte>(g.ToByteArray))
不是我要的。 这将分配一个新的数组,将字节复制到该数组,并创建一个引用新分配的数组的Span。 通过这样的跨度修改字节不会修改Guid。
您可以将Guid
强制为数组
struct MyStruct {
public Guid g;
}
...
var s = new MyStruct();
var span = new Span<byte>(s.g.ToByteArray());
span[2] = 4;
注意 :以上内容不会修改原始结构。 但是,正如您指出的那样,您可以在unsafe
执行此操作
var s = new MyStruct();
var span = new Span<byte>(&s , Marshal.SizeOf(s));
// woah it just become mutable
span[2] = 4;
在.Net Core 2.1或更高版本中尝试以下操作:
Span<MyStruct> valSpan = MemoryMarshal.CreateSpan(ref mystruct, 1);
Span<byte> span = MemoryMarshal.AsBytes(valSpan);
但是请谨慎使用,因为GC可以移动引用类型,所以您的结构中不应包含任何指针或引用类型。 实际上,它将执行运行时检查,并在执行时引发异常。
查看Span
类的构造函数,创建Span
的唯一方法是提供托管数组或指针。
但是Guid
由1个int,2个短裤和8个字节组成,而不是字节数组。
因此这是不可能的(至少现在不是这样)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.