简体   繁体   English

我可以得到一个跨度 <byte> 引用非字节类型的结构成员字段?

[英]Can I get a Span<byte> that references a struct member field of non-byte type?

Say I have a struct like the following: 说我有一个类似下面的结构:

struct MyStruct {
  Guid g;
}

Is it possible to get a Span<byte> that references the bytes of the struct? 是否有可能获得引用该结构字节的Span<byte>

struct MyStruct {
  Guid g;

  public void Foo() {
    Span<byte> bytes = ???
  }
}

Such that bytes would be a Span<byte> of length 16 that would allow reading and writing the individual bytes of the Guid field directly. 这样, bytes将是长度为16的Span<byte> ,这将允许直接读取和写入Guid字段的各个字节。

I can do something similar with unsafe code, but it seems that this should now be possible with safe code via span, but I can't figure out how to produce the span. 我可以对不安全的代码执行类似的操作,但似乎现在应该可以通过跨度的安全代码来实现,但是我无法弄清楚如何产生跨度。

Edit: Clarify that I want a Span that points to the actual storage location of the Guid. 编辑:澄清一下,我想要一个跨度指向Guid的实际存储位置。 Meaning new Span<byte>(g.ToByteArray)) is not what I'm looking for. 意思是new Span<byte>(g.ToByteArray))不是我要的。 That will allocate a new array, copy the bytes to the array, and create a Span referencing the newly allocated array. 这将分配一个新的数组,将字节复制到该数组,并创建一个引用新分配的数组的Span。 Modifying bytes via such a span will not modify the Guid. 通过这样的跨度修改字节不会修改Guid。

You can force the Guid to an array 您可以将Guid强制为数组

struct MyStruct {
   public Guid g;
}

...

var s = new MyStruct();
var span = new Span<byte>(s.g.ToByteArray());
span[2] = 4;

Note : The above will not modify the original struct. 注意 :以上内容不会修改原始结构。 However, as you pointed out, you can do this with unsafe 但是,正如您指出的那样,您可以在unsafe执行此操作

var s = new MyStruct();
var span = new Span<byte>(&s , Marshal.SizeOf(s));

// woah it just become mutable 
span[2] = 4;

Try this in .Net Core 2.1 or above: 在.Net Core 2.1或更高版本中尝试以下操作:

            Span<MyStruct> valSpan = MemoryMarshal.CreateSpan(ref mystruct, 1);
            Span<byte> span = MemoryMarshal.AsBytes(valSpan);

But use with caution, you should not contain any pointer or reference type in your struct, since GC can move reference type. 但是请谨慎使用,因为GC可以移动引用类型,所以您的结构中不应包含任何指针或引用类型。 Actually, it will do runtime check and throw an exception if you do that. 实际上,它将执行运行时检查,并在执行时引发异常。

Look at the constructors of Span class, the only ways to create a Span is providing a managed array or a pointer. 查看Span类的构造函数,创建Span的唯一方法是提供托管数组或指针。

But Guid is made up with 1 int, 2 shorts and 8 bytes, not a byte array. 但是Guid由1个int,2个短裤和8个字节组成,而不是字节数组。

So it's impossible (at least not now). 因此这是不可能的(至少现在不是这样)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM