说我有一个类似下面的结构:
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。
答案 0 :(得分:3)
您可以将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;
答案 1 :(得分:1)
在.Net Core 2.1或更高版本中尝试此操作:
Span<MyStruct> valSpan = MemoryMarshal.CreateSpan(ref mystruct, 1);
Span<byte> span = MemoryMarshal.AsBytes(valSpan);
但是要谨慎使用,因为GC可以移动引用类型,所以结构中不应包含任何指针或引用类型。实际上,它会执行运行时检查并抛出异常。
答案 2 :(得分:0)
看看Span
类的构造函数,创建Span
的唯一方法是提供托管数组或指针。
但是Guid
由1个整数,2个短裤和8个字节组成,而不是字节数组。
所以这是不可能的(至少现在不是这样)。