Object Serialization - CodeProject

:

Introduction

Serializing objects is a pretty common task that most softwares do, in C# you either use ISerializable interface or simple manually write/read lines, whatever you use, you will find a code with decent or even hundreds of lines of code just for serializing.

This library lets you serialize a whole class/struct just writing a few lines with almost no time overhead added by generating the de/serialize methods.

Background

All this library does is map classes implementing the SerializableObject attribute, generates C# code and then compiles it.

Since this is the very first version, there is not much to say, the library at the moment only supports binary serialization using BinaryWriter and BinaryReader classes. The next stage will be possible more features for binary serialization (if requested), then start with XML serialization.

Current features are:

  • Possibility to save generated .cs files
  • Support for all numeric datatype, string and byte[]
  • Support custom serialize/deserialize methods (so any object can be serialized)
  • Support for enums
  • Support for objects whose size may change
  • Choosing custom encoding
  • Default serializer methods if needed

Using the Code

Since it's in a really basic stage, usage is pretty simple, here is a quick example (that can be downloaded).

Note

  • A string property implementing the SerializableElement attribute will be serialized with fixed length as default, and since default fixed length is 0, may result in no serialization of the element
  • A custom serializer implementation must contain static methods for serializing the required datatype
public class CustomSerializer
{
    public static byte[] Serialize(string value)
    {
        return Encoding.ASCII.GetBytes(new string(value.Reverse().ToArray()));
    }
    public static string Deserialize(byte[] value)
    {
        return Encoding.ASCII.GetString(value);
    }
}
[SerializableObject(SerializedElements.All, EncodingName = "ASCII")]
public class Person
{
    // Every property with dynamic length (string and byte[]) will be serialized
    // with dynamic length as default
    public string Name { get; set; }

    public string LastName { get; set; }

    public int Age { get; set; }

    // Fixed length will write the value, then fill with zeros if needed
    [SerializableElement(FixedLength = 23)]
    public string Extra { get; set; }

    // Every property implementing the serializable elements will have the DynamicLength property
    // in false as default and FixedLength in 0, this resumes in no serialization at all
    // Basically, set DynamicLength to true or set a FixedLength by yourself
    [SerializableElement(DynamicLength = true, CustomSerializerType = typeof(CustomSerializer))]
    public string Extra1 { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        SerializerFactory factory = new SerializerFactory
    (Language.Binary, "Serializer", Assembly.GetExecutingAssembly());
        factory.DumpFiles = true;
        factory.Initialize();
        var personSerializer = factory.GetBinarySerializer<person>();

        Person person1 = new Person();
        person1.Name = "Rodrigo";
        person1.Age = 20;
        person1.LastName = "Whiteley";
        person1.Extra = "this message will be cut";
        person1.Extra1 = "gnirts desrever a si siht";

        byte[] serializedPerson = personSerializer.Serialize(person1);

        Person person2 = new Person();
        personSerializer.Deserialize(person2, serializedPerson);

        Console.WriteLine("Person Name: {0} {1}", person2.Name, person2.LastName);
        Console.WriteLine("Person Age: {0}", person2.Age);
        Console.WriteLine("Person Extra: {0}", person2.Extra);
        Console.WriteLine("Person Extra1: {0}", person2.Extra1);

        Console.WriteLine("\nPress any key to exit...");
        Console.ReadKey();
    }
}</person>

Points of Interest

All the mapped classes go to a static cache, so you can start multiple SerializerFactory and map once each class, at the moment you should not do this ever, but in the near future XMLs should be supported too, so multiple SerializerFactory instance may be used for different serialization types.

History

  • 29/03/2015: First release, binary serialization