本文介绍了C# - 结构序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小类,我想用它来序列化结构.我想知道两件事:

I have got a small class that I would like to use for serializing structs. I would like to know two things:

  • 性能问题.因为我正在传递 Object - 它只传递一个引用,而不是结构的副本?由于我返回的是 T 类型的对象,所以它也只传递一个引用?

  • Performance issue. Since I am passing Object - it passes just a reference, not a copy of the struct? And since I am returning object of type T it also only passes a reference?

正确性问题.这种序列化是否适用于所有结构?我的意思是 - 这些方法有没有可能不起作用?

Correctness issue. Will this serialization work for all structs? I mean - is there a possibility where those methods will not work?

public static byte[] ToByteArray(Object obj)
{
    int size = Marshal.SizeOf(obj);
    byte[] arr = new byte[size];
    IntPtr ptr = Marshal.AllocHGlobal(size);

    Marshal.StructureToPtr(obj, ptr, true);
    Marshal.Copy(ptr, arr, 0, size);
    Marshal.FreeHGlobal(ptr);

    return arr;
}

public static T ToStructure<T>(byte[] arr) where T : new()
{
    T str = new T();

    int size = Marshal.SizeOf(str);
    IntPtr ptr = Marshal.AllocHGlobal(size);

    Marshal.Copy(arr, 0, ptr, size);
    str = (T)Marshal.PtrToStructure(ptr, str.GetType());
    Marshal.FreeHGlobal(ptr);

    return str;
}

谢谢,伙计们!

编辑

我现在指定这些是结构体.现在什么都没有被复制?

I now specify that these are structs. Nothing is being copied now?

    public static byte[] ToByteArray<T>(ref T str) where T : struct
    {
        int size = Marshal.SizeOf(str);
        byte[] arr = new byte[size];
        IntPtr ptr = Marshal.AllocHGlobal(size);

        Marshal.StructureToPtr(str, ptr, true);
        Marshal.Copy(ptr, arr, 0, size);
        Marshal.FreeHGlobal(ptr);

        return arr;
    }

    public static T ToStructure<T>(byte[] arr) where T : struct
    {
        T str = default(T);

        int size = Marshal.SizeOf(str);
        IntPtr ptr = Marshal.AllocHGlobal(size);

        Marshal.Copy(arr, 0, ptr, size);
        str = (T)Marshal.PtrToStructure(ptr, str.GetType());
        Marshal.FreeHGlobal(ptr);

        return str;
    }

推荐答案

  1. 这不会正确序列化引用(即非原始和非结构类型的任何字段).
  2. 它不包括类型数据
    • 这使得它不适用于事先并非所有类型都已知或某些类型自序列化时间以来略有变化的情况.

为什么不在重新发明轮子之前了解现有解决方案?序列化指南 文章说在 .NET 框架中实现了 3 种序列化技术,它们具有不同的特性并且针对不同的目的进行了定制.

Why not learn about the existing solutions before reinventing the wheel? The Serialization Guidelines article says there are 3 serialization techniques implemented in the .NET framework that have different characteristics and are tailored for different purposes.

以下是 中给出的最简单的第三种技术的示例.NET 中的对象序列化 文章.它的存在是为了重建一个与原始对象具有完全相同类型和内部数据的对象(这意味着,序列化包括它引用的对象).

Here's an example of the simplest, 3rd technique given as example in the Object Serialization in .NET article. It exists to reconstruct an object with exactly the same type and internal data as the original one (which means, serialization includes the objects it references).

>>> l=System.Collections.Generic.List[System.Drawing.Point]\
([System.Drawing.Point(*(random.randint(1,1000) for _ in range(2))) for _ in range(5)])
>>> l
List[Point]([<System.Drawing.Point object at 0x0000000000000233 [{X=491,Y=874}]>
, <System.Drawing.Point object at 0x0000000000000234 [{X=819,Y=595}]>, <System.D
rawing.Point object at 0x0000000000000235 [{X=456,Y=625}]>, <System.Drawing.Poin
t object at 0x0000000000000236 [{X=583,Y=29}]>, <System.Drawing.Point object at
0x0000000000000237 [{X=329,Y=212}]>])
>>> szr=System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()
>>> stm=System.IO.MemoryStream()
>>> szr.Serialize(stm,l)
>>> stm.Length
481L
>>> bytes=stm.GetBuffer()
>>> s=''.join(chr(b) for b in bytes)
>>> s
u'\x00\x01\x00\x00\x00\xff\xff\xff\xff\x01\x00\x00\x00\x00\x00\x00\x00\x0c\x02\x
00\x00\x00QSystem.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f
5f7f11d50a3a\x04\x01\x00\x00\x00\x8c\x01System.Collections.Generic.List`1[[Syste
m.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToke
n=b03f5f7f11d50a3a]]\x03\x00\x00\x00\x06_items\x05_size\x08_version\x04\x00\x00\
x16System.Drawing.Point[]\x02\x00\x00\x00\x08\x08\t\x03\x00\x00\x00\x05\x00\x00\
x00\x00\x00\x00\x00\x07\x03\x00\x00\x00\x00\x01\x00\x00\x00\x05\x00\x00\x00\x04\
x14System.Drawing.Point\x02\x00\x00\x00\x05\xfc\xff\xff\xff\x14System.Drawing.Po
int\x02\x00\x00\x00\x01x\x01y\x00\x00\x08\x08\x02\x00\x00\x00\xeb\x01\x00\x00j\x
03\x00\x00\x01\xfb\xff\xff\xff\xfc\xff\xff\xff3\x03\x00\x00S\x02\x00\x00\x01\xfa
\xff\xff\xff\xfc\xff\xff\xff\xc8\x01\x00\x00q\x02\x00\x00\x01\xf9\xff\xff\xff\xf
c\xff\xff\xffG\x02\x00\x00\x1d\x00\x00\x00\x01\xf8\xff\xff\xff\xfc\xff\xff\xffI\
x01\x00\x00\xd4\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

这篇关于C# - 结构序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 18:36