Simple Example on serialization, it is more managed. it also helps to version your objects for backward compatibility.
Also can be used not only for files but it can be used for network and memory steams.
Code:
public interface ISerializable
{
bool Serialize(BinaryWriter stream);
bool Deserialize(BinaryReader stream);
}
The base object you want to serialize and deserialize, and a serialization version for backwards compatibility. For serialization you can also add serialization versions methods, if you want to serialize backwards or to not be too messy
Code:
public class World : ISerializable
{
private const int m_nVersion = 2;
// added in V1
public int m_nX, m_nY, m_nW, m_nH;
// Added min V2
public List<Player> m_players = new List<Player> ();
#region Constructors
public World ( int nX, int nY, int nW, int nH)
{
m_nX = nX;
m_nY = nY;
m_nW = nW;
m_nH = nH;
}
#endregion Constructors
#region ISerializable
public bool Serialize (BinaryWriter stream)
{
stream.Write (m_version);
// added in V1
stream.Write (m_nX);
stream.Write (m_nY);
stream.Write (m_nW);
stream.Write (m_nH);
// Added min V2
stream.Write (m_players.Count);
foreach (Player player in m_players) {
player.Serialize (stream);
}
}
public bool Deserialize (BinaryReader stream)
{
bool bResult = false;
int nVersion = stream.ReadInt32 ();
switch (nVersion) {
case 1:
{
bResult = DeserializeV1 (stream);
}
break;
case 2:
{
bResult = DeserializeV2 (stream);
}
break;
}
return bResult;
}
#endregion ISerializable
private bool DeserializeV1 (BinaryReader stream)
{
m_nX = stream.ReadInt32 ();
m_nY = stream.ReadInt32 ();
m_nW = stream.ReadInt32 ();
m_nH = stream.ReadInt32 ();
return true;
}
private bool DeserializeV2 (BinaryReader stream)
{
bool bresult = DeserializeV1 (stream);
int nCount = stream.ReadInt32 ();
for (int nIndex = 0; nIndex < nCount; nIndex++) {
Player player = new Player ();
player.Deserialize (stream);
m_players.Add (player);
}
return bresult;
}
}
The Player class as a sub object for deserialization
Code:
public class Player : ISerializable
{
private const int m_nVersion = 1;
// added in V1
int m_nX, m_nY;
#region Constructors
public Player (int nX, int nY)
{
m_nX = nX;
m_nY = nY;
}
#endregion Constructors
#region ISerializable
public bool Serialize (BinaryWriter stream)
{
stream.Write (m_version);
// added in V1
stream.Write (m_nX);
stream.Write (m_nY);
}
public bool Deserialize (BinaryReader stream)
{
bool bResult = false;
int nVersion = stream.ReadInt32 ();
switch (nVersion) {
case 1:
{
bResult = DeserializeV1 (stream);
}
break;
}
return bResult;
}
#endregion ISerializable
private bool DeserializeV1 (BinaryReader stream)
{
m_nX = stream.ReadInt32 ();
m_nY = stream.ReadInt32 ();
return true;
}
}
How to use it, plus the code will not be messy.
Code:
World myWorld = new World (0, 0, 100, 100);
myWorld.AddPlayer (new Player (50, 53));
myWorld.AddPlayer (new Player (80, 25));
myWorld.AddPlayer (new Player (10, 75));
using (MemoryStream memoryStream = new MemoryStream ()) {
using (BinaryWriter writer = new BinaryWriter (Stream)) {
myWorld.Serialize (writer);
}
using (BinaryReader reader = new BinaryReader (Stream)) {
myWorld.Deserialize (reader);
}
}