So was playing about with Binary serialization, and think I have a nice base class you might want to use if you ever want serialize your classes. This is the base class
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
namespace SerializationXNA
{
[Serializable]
public class SerializableBase<T> : ISerializable
{
/// <summary>
/// ctor
/// </summary>
public SerializableBase() { }
/// <summary>
/// ctor
/// </summary>
/// <param name="info">Data to be serialized</param>
/// <param name="context">Streaming context</param>
public SerializableBase(SerializationInfo info, StreamingContext ctxt)
: this()
{
PropertyInfo[] properties = this.GetType().GetProperties();
int propertyCount = properties.Length;
for (int p = 0; p < propertyCount; p++)
properties[p].SetValue(this, info.GetValue(properties[p].Name, properties[p].PropertyType), null);
}
/// <summary>
/// Method to serialize the object
/// </summary>
/// <returns></returns>
public static byte[] Serialize(T objectInsatnce)
{
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream memStream = new MemoryStream();
formatter.Serialize(memStream, objectInsatnce);
byte[] buffer = memStream.ToArray();
memStream.Close();
return buffer;
}
/// <summary>
/// Method to deserialize the object from a byte array
/// </summary>
/// <param name="buffer">byte array holding the serialized object</param>
/// <returns>Deserialized instance of the object</returns>
public static T Deserialize(byte[] buffer)
{
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream memStream = new MemoryStream(buffer);
T retVal = (T)formatter.Deserialize(memStream);
memStream.Close();
return retVal;
}
/// <summary>
/// Needed to do binary serailization of this object
/// </summary>
/// <param name="info">Data to be serialized</param>
/// <param name="context">Streaming context</param>
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
PropertyInfo[] properties = this.GetType().GetProperties();
int propertyCount = properties.Length;
for (int p = 0; p < propertyCount; p++)
info.AddValue(properties[p].Name, properties[p].GetValue(this, null));
}
}
}
Not a great deal in there other than it has to have the Serializable class attribute and implement the ISerializable interface and uses a generic in it’s definition, there are two constructors, the second needed for de-serialization. We then have Serialize and Deserialize statics, both methods do exactly what they say and then finally we implement the ISerializable method GetObjectData.
So pretty simple stuff, this is how you can then derive from this to then use all the lovely serialization stuff in the base class
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
namespace SerializationXNA
{
[Serializable]
public class SerializableClass : SerializableBase<SerializableClass>
{
public bool IsDirty { get; set; }
public string Name { get; set; }
public Dictionary<string, object> ObjDictionary { get; set; }
public List<string> StringList { get; set; }
public SerializableClass()
{
IsDirty = false;
Name = string.Empty;
ObjDictionary = new Dictionary<string, object>();
StringList = new List<string>();
}
public SerializableClass(SerializationInfo info, StreamingContext ctxt)
: base(info, ctxt)
{ }
}
}
As you can see a pretty simple class, has 4 properties and a couple of constructors, but as we have derived from SerializableBase class we get all the serializable goodness, so this is how you could implement it
classToSerialize.IsDirty = true;
classToSerialize.Name = "Date To serialize";
classToSerialize.ObjDictionary.Add("One", "One");
classToSerialize.ObjDictionary.Add("Two", 3);
classToSerialize.StringList.Add("Hello");
classToSerialize.StringList.Add("World");
byte[] buffer = SerializableClass.Serialize(classToSerialize);
SerializableClass deserializedClass = SerializableClass.Deserialize(buffer);
deserializedClass.Name = "Deserialized data";
The great thing about this is that you can go and add as many properties as you like and you wont have to change any of the serialization code as it will automatically pick up the new properties :)
EDIT
Just altered the base class so it’s now WP7 friendly, I guess you could go 100% with the DataContractSerializer though…
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Runtime.Serialization;
#if WINDOWS
using System.Runtime.Serialization.Formatters.Binary;
#endif
using System.IO;
namespace SerializationXNA
{
#if WINDOWS
[Serializable]
#endif
public class SerializableBase<T>
#if WINDOWS
: ISerializable
#endif
{
/// <summary>
/// ctor
/// </summary>
public SerializableBase() { }
#if WINDOWS
/// <summary>
/// ctor
/// </summary>
/// <param name="info">Data to be serialized</param>
/// <param name="context">Streaming context</param>
public SerializableBase(SerializationInfo info, StreamingContext ctxt)
: this()
{
PropertyInfo[] properties = this.GetType().GetProperties();
int propertyCount = properties.Length;
for (int p = 0; p < propertyCount; p++)
properties[p].SetValue(this, info.GetValue(properties[p].Name, properties[p].PropertyType), null);
}
#endif
/// <summary>
/// Method to serialize the object
/// </summary>
/// <returns></returns>
public static byte[] Serialize(T objectInsatnce)
{
#if WINDOWS
BinaryFormatter formatter = new BinaryFormatter();
#else
DataContractSerializer formatter = new DataContractSerializer(typeof(T));
#endif
MemoryStream memStream = new MemoryStream();
#if WINDOWS
formatter.Serialize(memStream, objectInsatnce);
#else
formatter.WriteObject(memStream, objectInsatnce);
#endif
byte[] buffer = memStream.ToArray();
memStream.Close();
return buffer;
}
/// <summary>
/// Method to deserialize the object from a byte array
/// </summary>
/// <param name="buffer">byte array holding the serialized object</param>
/// <returns>Deserialized instance of the object</returns>
public static T Deserialize(byte[] buffer)
{
#if WINDOWS
BinaryFormatter formatter = new BinaryFormatter();
#else
DataContractSerializer fomratter = new DataContractSerializer(typeof(T));
#endif
MemoryStream memStream = new MemoryStream(buffer);
#if WINDOWS
T retVal = (T)formatter.Deserialize(memStream);
#else
T retVal = (T)fomratter.ReadObject(memStream);
#endif
memStream.Close();
return retVal;
}
#if WINDOWS
/// <summary>
/// Needed to do binary serailization of this object
/// </summary>
/// <param name="info">Data to be serialized</param>
/// <param name="context">Streaming context</param>
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
PropertyInfo[] properties = this.GetType().GetProperties();
int propertyCount = properties.Length;
for (int p = 0; p < propertyCount; p++)
info.AddValue(properties[p].Name, properties[p].GetValue(this, null));
}
#endif
}
}
No comments:
Post a Comment