Readonly is in the eye of the beholder
One of my most used feature in the 3.5 compiler for .Net is automatic properties. In case you are not familiar, here is a recap.
Traditionally, properties work with a backing field. For example:
private String _someValue;
public String SomeValue
{
get
{
return _someValue;
}
set
{
_someValue = value;
}
}
Automatic properties under the 3.5 compiler allow this code to be represented as:
public String SomeValue
{
get;
set;
}
Automatic properties make code cleaner and easier to use. Additionally, they also require less testing. There isn’t any point testing their logic of accessing the backing field to ensure correct operation and they appear with 100% code coverage. My biggest gripe though is that they don’t truly support readonly definitions.
The documentation on MSDN says:
Auto-implemented properties must declare both a get and a set accessor. To create a readonly auto-implemented property, give it a private set accessor.
The implementation of automatic properties by the compiler define that readonly automatic properties are achieved by assigning a private scope to the set accessor. For example:
public String SomeValue
{
get;
private set;
}
Unfortunately, I think this is a cheap bandaid hack. It doesn’t make the property truly readonly. It is technically readonly, but only from the perspective of external callers. Internal to the class, the property is not readonly because the private scope makes setting the property value possible. This doesn’t protect the value of the backing field which is what a true readonly property should be able to support. See here for the MSDN documentation on the readonly keyword.
I would like to see this changed. Without understanding the complexities of writing compilers, I would think that this change would not be too significant. The simple fix would be to enhance the syntax of the automatic property setter definition. If the private set statement could be enhanced to understand a readonly keyword, then the compile could mark the backing field with the same readonly keyword. For example:
public String SomeValue
{
get;
private readonly set;
}
This would then be interpreted by the compiler as something like this:
private readonly String _someValue;
public String SomeValue
{
get
{
return _someValue;
}
set
{
_someValue = value;
}
}
I have added this as a suggestion to Microsoft Connect here.