But ideally I don't want the deprecated field to be public either.
Well, it is pretty well hidden by the two attributes - but ultimately
XmlSerializer works on public properties. If you have .NET 3.0,
another option is DataContractSerializer (shown below), since this can
serialize private members; and a third option is custom serialization
(IXmlSerializable), but this is considerably more work.
Quote:
As for public fields - in this case the class is just a holder for
fairly raw data, where no particular validation is needed.
|
Then in VS2008 / C# 3, auto implemented properties are definitely the
way to go.
Quote:
And the beauty of C# is you can change public fields to properties at
any point and existing code will continue to compile.
|
That isn't entirely true... first: it forces you to rebuild everything
that references it, and second: there are cases when this simply isn't
true; two obvious examples come to mind (there are others):
* using the field as a "ref" or "out" parameter to a method [can't use
properties as "ref" or "out"]
* if the field represents a mutable struct [which you shouldn't have
anyway], and you are changing nested properties [change gets discarded
with a property]
It will almost certainly break binary serialization, too.
Marc
## DataContract example ##
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;
[DataContract(Namespace="")]
public sealed class MyClass
{
[DataMember(IsRequired = false)]
public int Width { get; set; }
[DataMember(IsRequired=false)]
public int Height { get; set; }
[DataMember(Name="Area", IsRequired=false,
EmitDefaultValue=false)]
private int? AreaFacade
{
get { return null; }
set {
if (value.HasValue)
{
Width = Height = (int)Math.Sqrt(value.Value);
}
}
}
public override string ToString()
{
return string.Format("{0}x{1}", Width, Height);
}
}
static class Program
{
static void Main(string[] args)
{
DataContractSerializer xs = new
DataContractSerializer(typeof(MyClass));
MyClass item = new MyClass { Width = 3, Height = 5 };
StringWriter writer = new StringWriter();
using (XmlWriter xw = XmlWriter.Create(writer))
{
xs.WriteObject(xw, item);
xw.Close();
}
string xml = writer.ToString();
Console.WriteLine(xml);
using (XmlReader xr = XmlReader.Create(new
StringReader(@"<MyClass><Area>25</Area></MyClass>")))
{
MyClass oldStyle = (MyClass)xs.ReadObject(xr);
Console.WriteLine(oldStyle);
}
using (XmlReader xr = XmlReader.Create(new
StringReader(@"<MyClass><Height>3</Height><Width>7</Width></
MyClass>")))
{
MyClass newStyle = (MyClass)xs.ReadObject(xr);
Console.WriteLine(newStyle);
}
}
}