A few notes on the readonly field vs readonly property post…

First, Tom (not Ted) pointed out that I removed his use of [DebuggerStepThrough] on the get accessor. I did it to simplify things, but it is a useful thing to do.

Maurits asked, “What would be the drawback of rearchitecturing C# to make public variables compile to public get-only properties?”.

Well, I guess I don’t see a lot of advantage in doing that, so I guess the chief drawback I’d see is “insufficient utility versus the added complexity”. We did play around with different syntaxes that could be used to write properties without having to write the accessors, but it turned out that they either 1) Didn’t cover the important scenarios or 2) were as complex as writing the property. We elected not to do that.

Bertrand Le Roy pointed out that there are some frameworks that work with properties but not with public fields. I find this pretty annoying, but this does mean that if you want to use data binding (for example), you’ll have to define the properties.

Bjorn Reppen wrote a whole post on his opinion, which I really won’t comment on except to say that I’m a firm believer in YAGNI.

Peter Ritchie wrote, “You appear to be contradicting the (framework desgin) Guidelines by suggesting readonly instance fields are a better choice under certain circumstances”.

When .NET first came out, there was some talk about writing some general coding guidelines for C#, but we realized that coding guidelines are very specific to teams and can lead to religious discussions, so we opted not to.

Which meant that the only reference we had was the framework design guidelines, which was unfortunate.

The Framework Design Guidelines are great – if you are building a framework. But most people aren’t building frameworks – they’re building applications, or their building libraries that their group uses directly. In those cases, I think you have to weigh the benefits and the costs.

I think I could have made it clearer that many frameworks fit into the “update this assembly separately” clause.

Finally, there were a couple comments properties being more flexible. My point was that paying for flexibility that you don’t need is the wrong place to put your money.

Comments (4)

  1. Peter Ritchie says:

    Yes, very unfortunate that the only "offical" code standards/guidelines don’t really apply to "most people".  Especially unfortunate in that it re-enforces methodologies (e.g. "never make an instance field public") that are essentially "religious" blanket statements.  Most of the guidance from Guidelines will be telescoped into projects to which it may not apply.

    Eric, will you do us the favour and write/spearhead a new ".NET Design Guidelines" initiative as the old version is largely considered replaced by Framework Design Guidelines.  It’s pretty clear that this is Microsoft’s position (reinforced by many of the rules in Code Analysis).


  2. Hmm, this got me thinking of the public vs published issue.

    Are there any plans or have there been any suggestions for a "published" attribute?

    The way I envision it, you would need two attributes:  (1) An assembly level attribute (i e "AssemblyUsesPublishedConventionAttribute" or something. Yeah, bad example) saying that this assembly uses the published convention. (2) A member/interface attribute ("PublishedAttribute") saying that the decorated (public) member/interface is in fact published.

    The result would be that any non-published public members of the assembly that are used by client code would cause a compiler warning (or perhaps even error if made configureable) similar to the effect of the obsolete attribute. So, approximately an inverted obsolete attribute.

    I think that would be very useful from a framework/component POV.  Right now we too, like many others, use the "Internal" convention. We also use the obsolete attribute with a text saying it is internal, unpublished and unsupported . But it would be nicer if there was some direct support.

    Sorry for the long comment.

  3. One decision I go through we decided readonly Field vs property is whether I will be perfoming DataBinding on it.  Using the DataSource controls seemed to require a Property and not a field for DataBinding.