如何使这些结构函数通用?

pfi*_*rno 5 c# generics struct

我有这两个函数将流读入缓冲区并将其加载到给定的结构中.

    TestStruct1 ReadRecFromStream2(Stream stream)
    {
        byte[] buffer = new byte[Marshal.SizeOf(typeof(TestStruct1))];
        stream.Read(buffer, 0, 128);
        GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
        try
        {
            return (TestStruct1)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(TestStruct1));
        }
        finally
        {
            handle.Free();
        }
    }

    TestStruct2 ReadRecFromStream(Stream stream)
    {
        byte[] buffer = new byte[Marshal.SizeOf(typeof(TestStruct2))];
        stream.Read(buffer, 0, 128);
        GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
        try
        {
            return (TestStruct2)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(TestStruct2));
        }
        finally
        {
            handle.Free();
        }
    }
Run Code Online (Sandbox Code Playgroud)

我想将它们组合成一个通用函数来获取任何一个结构,我只是不确定这样做的正确方法是什么.

这是正确的方法吗?

    private T ReadRecFromStream<T>(Stream stream)
    {
        byte[] buffer = new byte[Marshal.SizeOf(typeof(T))];
        stream.Read(buffer, 0, HeaderSize);
        GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
        try
        {
            return (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
        }
        finally
        {
            handle.Free();
        }
    }
Run Code Online (Sandbox Code Playgroud)

Seb*_*ann 2

也许您可以使用这些方法来转换 byte[] 和 byte[]:

public static unsafe byte[] ToBytes<T>(this T value)
    where T : struct
{
    var result = new byte[Marshal.SizeOf(typeof(T))];
    fixed (byte* b = &result[0])
    {
        var p = new IntPtr(b);
        Marshal.StructureToPtr(value, p, false);
    }

    return result;
}

public static unsafe T FromBytes<T>(this byte[] bytes, int startIndex = 0)
    where T : struct
{
    fixed (byte* b = &bytes[startIndex])
    {
        var p = new IntPtr(b);
        return (T)Marshal.PtrToStructure(p, typeof(T));
    }
}
Run Code Online (Sandbox Code Playgroud)

使用这个你的方法可以更改为:

T ReadRecFromStream<T>(Stream stream)
    where T : struct
{
    byte[] buffer = new byte[Marshal.SizeOf(typeof(T))];
    stream.Read(buffer, 0, buffer.Length);
    return buffer.FromBytes<T>()
}
Run Code Online (Sandbox Code Playgroud)

阅读的效果类似。