gpt4 book ai didi

c# - 在不装箱的情况下将字节数组复制到通用类型

转载 作者:行者123 更新时间:2023-11-30 14:21:33 28 4
gpt4 key购买 nike

我正在开发一个 C# 类,其中我需要能够接收字节数组并将其复制到相同大小的通用变量。在 C/C++ 中,这样的事情(复制)很容易,但在 C# 中就没那么容易了。

MyClass<T>
{
public T Value = default(T);

public MyClass(byte[] bytes)
{
// how to copy `bytes` into `Value`?
}
}

我不想使用拳击。有没有办法使用编码(marshal)处理、反射或非托管/不安全代码来做到这一点?


我确实找到了 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];
}
}

您还可以使用 unsafe在最近的 C# 版本中(针对 T : unmanaged 约束):

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!");

或者您可以使用 sizeof(T)如果你有 T : unmanaged约束。 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# - 在不装箱的情况下将字节数组复制到通用类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54537522/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com