I have got a small class that I would like to use for serializing structs. I would like to know two things:
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 typeT
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; }
Thanks, guys!
EDIT
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;
}
FYI With generics you can constrain a method to just apply to structs with "where T:struct"
ToStructure
doesn't validate the binary dataWhy 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.
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).
(the code is in IronPython yet I hope it's readable enough to understand what's going on)