TypeReference和FieldInfo.SetValueDirect不是持久的

时间:2016-03-03 16:16:36

标签: c# struct

我使用TypedReference在FieldInfo.SetValueDirect(Practical uses of TypedReference)的结构中设置值。

总体目标是拥有一个通用的struct-to-buffer和buffer-to-struct函数来读取TCP数据流 直接进入c风格的结构(Bit fields in C#)。

感谢一些精彩的帖子,到目前为止,我的目的是为了我的目的,但我无法找到使TypeReference工作的方法。

此代码是项目的剥离版本,用于说明最后一个问题:正确填充结构 从缓冲区使用FieldInfo.SetValueDirect(),但是当我离开例程时它会失去范围。

    public class structL4
    {
        public UInt16 Label;
    }

    static class StructConvert
    {
        public static void BufferToStruct<T>(byte[] buffer, int offset, T t) where T : struct
        {
            UInt16 val;
            foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
            {
                val = BitConverter.ToUint16(buffer,offset);
                TypedReference reference = __makeref(t);
                f.SetValueDirect(reference, val); // t.Label now contains the right value but is lost
            }
        }

        public static void StructToBuffer<T>(T t, byte[] buffer, int offset) where T : struct
        {
            UInt16 val;
            foreach (System.Reflection.FieldInfo f in t.GetType().GetFields())
            {
                val = (UInt16)f.GetValue(t);
                Array.Copy(BitConverter.GetBytes(val), 0, buffer, offset, sizeof(UInt16));
            }
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        structL4 L0 = new structL4();
        structL4 L1 = new structL4();
        byte[] buffer = new byte[4];

        L0.Label = 0x8C54;

        StructConvert.StructToBuffer(L0, buffer, 0);  // works
        StructConvert.BufferToStruct(buffer,0,L1);    // does not work.
    }

我希望BufferToStruct()能够通过引用对传递的结构进行操作,因此我不必分配它,但是我很难找到编译器满意的解决方案。

总的来说这个想法很好,至少对于StructToBuffer(),我将使用几十个按位C型结构。

我使用TypeReference和FieldInfo方法有点超出了我的联盟;只在短时间内使用过C#。任何帮助非常感谢!

1 个答案:

答案 0 :(得分:0)

由于复制了“值类型”并且默认情况下将副本传递给方法,因此不会修改您的实际结构。

您要么返回一个结构并指定它,要么通过ref传递结构。

public static void BufferToStruct<T>(byte[] buffer, int offset, ref T t) where T : struct//Note the ref modifier

然后将其称为

StructConvert.BufferToStruct(buffer,0,ref L1);