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

时间:2016-03-24 13:54:01

标签: 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();
        }
    }

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

这是正确的方法吗?

    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();
        }
    }

1 个答案:

答案 0 :(得分:2)

也许你可以使用这些方法来转换为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));
    }
}

使用此方法可以将您的方法更改为:

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>()
}

阅读会起到类似作用。