Skip to content

Instantly share code, notes, and snippets.

@Orlys
Last active April 9, 2020 11:50
Show Gist options
  • Save Orlys/06441ccc56a7ad87eba0ca40f0f5b469 to your computer and use it in GitHub Desktop.
Save Orlys/06441ccc56a7ad87eba0ca40f0f5b469 to your computer and use it in GitHub Desktop.
namespace SelfSerialization
{
using System;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
public class BinarySerializer : Serializer<BinarySerializer>
{
public override byte[] Serialize(object graph)
{
var b = new BinaryFormatter();
using var ms = new MemoryStream();
b.Serialize(ms, graph);
return ms.ToArray();
}
public override T Deserialize<T>(byte[] payload)
{
var b = new BinaryFormatter();
using var ms = new MemoryStream(payload);
var graph = b.Deserialize(ms);
return (T)graph;
}
}
internal static class Cache<T> where T : new()
{
internal static readonly T Instance = new T();
}
public abstract class Serializer<TSelf> where TSelf : Serializer<TSelf>, new()
{
private static TSelf s_serializer = Cache<TSelf>.Instance;
public static TSelf Default
{
get
{
return s_serializer;
}
set
{
s_serializer = value is null ? Cache<TSelf>.Instance : value;
}
}
protected Serializer() { }
public abstract byte[] Serialize(object graph);
public abstract T Deserialize<T>(byte[] payload);
}
[Serializable] // This mark is for BinaryFormatter.
public abstract class Serializable<TSelf, TSerializer>
where TSelf : Serializable<TSelf, TSerializer>, new()
where TSerializer : Serializer<TSerializer>, new()
{
protected Serializable()
{
}
public static TSelf Deserialize(byte[] payload)
{
return Serializer<TSerializer>.Default.Deserialize<TSelf>(payload);
}
public byte[] Serialize()
{
return Serializer<TSerializer>.Default.Serialize(this);
}
}
}
namespace SelfSerialization.Test
{
[System.Serializable] // This mark is for BinaryFormatter.
public class User : Serializable<User, BinarySerializer>
{
public string Name { get; set; }
}
public class Program
{
public void Main(string[] args)
{
User user = new User { Name = "Orlys" };
// serializes instance to bytes.
byte[] binary = user.Serialize();
// do something here.
// deserializes instance from bytes.
User deserialied = User.Deserialize(binary);
System.Diagnostics.Debug.Assert(!ReferenceEquals(user, deserialied));
System.Diagnostics.Debug.Assert(user.Name.Equals(deserialied.Name));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment