You need to manually handle it using custom methods and marking them with the appropriate attributes OnSerializing/OnSerialized/OnDeserializing/OnDeserialized and manully determine how to initialize the values (if it can be done)
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializingattribute.aspx
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializedattribute.aspx
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.onserializedattribute.aspx
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.onserializingattribute.aspx
a better way is to determine the version before hand and use a strategy pattern to do the deserialization. This isn't always possible so use what I suggest in that case.
Update: The previous answer is only applicable to binary serialization. For regular Xml you can use this method.
class Program
{
static void Main(string[] args)
{
Deserialize(@"..\..\v1.xml");
}
private static Model Deserialize(string file)
{
XDocument xdoc = XDocument.Load(file);
var verAtt = xdoc.Root.Attribute(XName.Get("Version"));
Model m = Deserialize<Model>(xdoc);
IModelLoader loader = null;
if (verAtt == null)
{
loader = GetLoader("1.0");
}
else
{
loader = GetLoader(verAtt.Value);
}
if (loader != null)
{
loader.Populate(ref m);
}
return m;
}
private static IModelLoader GetLoader(string version)
{
IModelLoader loader = null;
switch (version)
{
case "1.0":
{
loader = new ModelLoaderV1();
break;
}
case "2.0":
{
loader = new ModelLoaderV2();
break;
}
case "3.0": { break; } //Current
default: { throw new InvalidOperationException("Unhandled version"); }
}
return loader;
}
private static Model Deserialize<T>(XDocument doc) where T : Model
{
Model m = null;
using (XmlReader xr = doc.CreateReader())
{
XmlSerializer xs = new XmlSerializer(typeof(T));
m = (Model)xs.Deserialize(xr);
xr.Close();
}
return m;
}
}
public interface IModelLoader
{
void Populate(ref Model model);
}
public class ModelLoaderV1 : IModelLoader
{
public void Populate(ref Model model)
{
model.City = string.Empty;
model.Phone = "(000)-000-0000";
}
}
public class ModelLoaderV2 : IModelLoader
{
public void Populate(ref Model model)
{
model.Phone = "(000)-000-0000";
}
}
public class Model
{
[XmlAttribute(AttributeName = "Version")]
public string Version { get { return "3.0"; } set { } }
public string Name { get; set; } //V1, V2, V3
public string City { get; set; } //V2, V3
public string Phone { get; set; } //V3 only
}
Depending on your requirements, this could be simplified into a single method on the model (or a model loader).
This could also be used for model validation after deserialization.
Edit: you can serialize using the following code
private static void Serialize(Model model)
{
XmlSerializer xs = new XmlSerializer(typeof(Model));
FileStream f = File.Create(@"..\..\v1.xml");
xs.Serialize(f, model);
f.Close();
}