Если вам не нужно богатство сериализации - если вы просто хотите записать структуру в байтовый массив, рассмотрите класс Marshal.
Например, рассмотрим приложение tar в C #. Формат tar основан на 512-байтовых блоках, а первый блок в серии имеет регулярную структуру. В идеале приложение хочет просто blitt данных из файла на диске, прямо в структуру . Метод Marshal.PtrToStructure делает это. Вот структура.
[StructLayout(LayoutKind.Sequential, Size=512)]
internal struct HeaderBlock
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
public byte[] name; // name of file.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] mode; // file mode
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] uid; // owner user ID
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] gid; // owner group ID
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] size; // length of file in bytes
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] mtime; // modify time of file
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] chksum; // checksum for header
// ... more like that... up to 512 bytes.
Тогда вот общий класс, который выполняет блиттинг.
internal class RawSerializer<T>
{
public T RawDeserialize( byte[] rawData )
{
return RawDeserialize( rawData , 0 );
}
public T RawDeserialize( byte[] rawData , int position )
{
int rawsize = Marshal.SizeOf( typeof(T) );
if( rawsize > rawData.Length )
return default(T);
IntPtr buffer = Marshal.AllocHGlobal( rawsize );
Marshal.Copy( rawData, position, buffer, rawsize );
T obj = (T) Marshal.PtrToStructure( buffer, typeof(T) );
Marshal.FreeHGlobal( buffer );
return obj;
}
public byte[] RawSerialize( T item )
{
int rawSize = Marshal.SizeOf( typeof(T) );
IntPtr buffer = Marshal.AllocHGlobal( rawSize );
Marshal.StructureToPtr( item, buffer, false );
byte[] rawData = new byte[ rawSize ];
Marshal.Copy( buffer, rawData, 0, rawSize );
Marshal.FreeHGlobal( buffer );
return rawData;
}
}
Вы можете использовать этот класс с любой структурой. Вы должны использовать LayoutKind.Sequential и ограничивать себя типами blittable (в основном примитивами и массивами одного и того же) для использования этого подхода. Он быстрый и эффективный с точки зрения кода, производительности и памяти, но он немного ограничен в том, как его можно использовать.
Получив байтовый массив, вы можете передать его через NetworkStream и т. Д., А затем десериализовать, используя тот же класс на другом конце.