c# – 将字节数组复制到通用类型而不进行装箱

c# – 将字节数组复制到通用类型而不进行装箱,第1张

概述我正在开发一个C#类,其中我需要能够接受一个字节数组并将其复制到相同大小的通用变量.在C/C++这样的事情(复制)会很容易,但在C#中并没有那么多. MyClass<T>{ public T Value = default(T); public MyClass(byte[] bytes) { // how to copy `bytes` into `Value`? } 我正在开发一个C#类,其中我需要能够接受一个字节数组并将其复制到相同大小的通用变量.在C/C++这样的事情(复制)会很容易,但在C#中并没有那么多.

MyClass<T>{  public T Value = default(T);  public MyClass(byte[] bytes)  {    // how to copy `bytes` into `Value`?  }}

我宁愿不使用拳击.有没有办法使用编组,反射或非托管/不安全代码?

我确实找到了this other post,但唯一建议的答案是行不通的,因为它使用拳击.

解决方法 如果您使用的是最新的.NET,则可以使用Span< T> (System.Buffers)为此:

class MyClass<T> where T : struct{    public T Value = default(T);    public MyClass(byte[] bytes)    {        Value = MemoryMarshal.Cast<byte,T>(bytes)[0];    }}

您还可以在最近的C#版本中使用unsafe(对于T:非托管约束):

class MyClass<T> where T : unmanaged{    public T Value = default(T);    public unsafe MyClass(byte[] bytes)    {        fixed (byte* ptr = bytes)        {            Value = *(T*)ptr; // note: no out-of-range check here; dangerous        }    }}

你也可以使用Unsafe.*方法(System.Runtime.CompilerServices.Unsafe)做一些事情.例如(注意没有约束):

class MyClass<T>{    public T Value = default(T);    public unsafe MyClass(byte[] bytes)    {        T local = default(T);        fixed (byte* ptr = bytes)        {            Unsafe.copy(ref local,ptr); // note: no out-of-range check here; dangerous        }        Value = local;    }}

如果要检查超出范围的问题:

if (bytes.Length < Unsafe.SizeOf<T>())    throw new InvalIDOperationException("Not enough data,fool!");

或者如果你有T:unmanaged约束,你可以使用sizeof(T).您不需要使用Span< T>解决方案(第一个),因为原始的Cast< byte,T>在这种情况下,将产生一个长度为零的跨度,[0]将适当地抛出.

我认为这也应该有效!

public unsafe MyClass(byte[] bytes){    Value = Unsafe.As<byte,T>(ref bytes[0]); // note: no out-of-range check here; dangerous}

完整示例(适用于net462):

using System;using System.Runtime.CompilerServices;struct Foo{    public int x,y;}class MyClass<T>{    public T Value = default(T);    public unsafe MyClass(byte[] bytes)    {        if (bytes.Length < Unsafe.SizeOf<T>())            throw new InvalIDOperationException("not enough data");        Value = Unsafe.As<byte,T>(ref bytes[0]);    }}static class P{    static voID Main() {        byte[] bytes = new byte[] { 1,2,3,4,5,6,7,8 };        var obj = new MyClass<Foo>(bytes);        var val = obj.Value;        Console.Writeline(val.x); // 67305985 = 0x04030201        Console.Writeline(val.y); // 134678021 = 0x08070605     }}
总结

以上是内存溢出为你收集整理的c# – 将字节数组复制到通用类型而不进行装箱全部内容,希望文章能够帮你解决c# – 将字节数组复制到通用类型而不进行装箱所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1215143.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存