To take the solution a little further to allow deserialization to work as well...
public class A
{
private int _id = -1;
public int Id
{
get { return _id; }
set
{
if (_id < 0)
throw new InvalidOperationException("...");
if (value < 0)
throw new ArgumentException("...");
_id = value;
}
}
}
This will allow Id
to be set exactly one time to a value greater than or equal to 0. Any attempts to set it after will result in InvalidOperationException
. This means that XmlSerializer
will be able to set Id
during deserialization, but it will never be able to be changed after. Note that if the property is a reference type then you can just check for null.
This may not be the best solution if you have a lot of read-only properties to serialize/deserialize as it would require a lot of boilerplate code. However, I've found this to be acceptable for classes with 1-2 read-only properties.
Still a hack, but this is at least a little more robust.