Public fields vs properties


 If you search on MSDN, you won’t find any general C# coding guidelines. When
people have asked how they should write their code, they often get pointed to the class
library design guidelines
. There is lots of good advice there, but not all
of it applies universally.

One of the guidelines says:

  • Do not use instance fields that are public or protected

it goes on to say that this is important because properties don’t version well.

Some people have taken this as an absolute rule, so I’ve been seeing lots of code
that uses properties on every class. If you don’t need the versioning advantages
of properties, you don’t need to spend the time writing lots of trivial properties
(those where the getter and setter don’t do anything special).

In fact, I’ll say that a bit stronger. You probably shouldn’t use properties unless
you need them, as it takes more work and makes your classes harder to read
and maintain.

So, when should you use properties that you don’t need? My suggestion is to only
use them at versioning boundaries. If a class and the classes that use it are always
compiled together, than properties don’t buy you any advantage. If they are compiled
separately, then using properties instead of fields looks like a better idea.

Or, to put it another way, writing trivial properties makes sense at the locations
where your component interfaces with other components.

 

 

 

Comments (15)

  1. Kevin Dente says:

    A common use for properties (rather than fields) is to allow validation of data values as they are being set on an object. Out of curiosity, has MS ever considered supporting a mechanism that allows for data validation without requiring all of the overhead of a full property declaration? I can imagine a sort of "anonymous" property, which gives you a chance to validate the property, but without requiring a private member to back up the property. Kind of like:

    public int Age
    {
    set
    {
    if (value < 0) throw new ArgumentException("You bozo");
    }
    }

    Then the property would be accessed as TheObj.Age, with no corresponding private member.

    Just a thought. It’s really syntactic sugar, and might not buy you enough to be worth it.

  2. Ian Ringrose says:

    I can set a break point on a properties get and set method. I can not set a break point on a field set/get, therefore I use properties.

  3. Sam Meldrum says:

    I don’t always know what the future may bring, therefore I use properties. I may change how I am storing the data inside my class but so long as I maintain my public properties I am ok; with fields I am hamstrung.

    I often find it useful to consider the class as a boundary even in situations where the class is internal (or a private nested class) as this makes the encapsulation tighter and often leads to me writing better code.

    A number of times I have written just such classes with public fields and at some later point changed that to properties. Admittedly, nothing ever broke because by definition, the calling code was compiled together, but it left me feeling that I’d not got it right first time – shouldn’t I have taken the fairly minimal hit up front and written properties from the off. It makes my internal classes look more like my public classes and my public classes are always written more carefully.

  4. Jim Sfekas says:

    Actually, I don’t think the readability issue is that big a deal. If you just put all your properties in a code region, then you can keep them out of your way until you have a reason to look.

  5. Constraints on properties, while nifty, would have the effect of having to declare a whole sub-section of the language to deal with the constraints, and that can be costly (as the benefits are not immediately clear, people have to learn a whole new subset of the language, etc, etc). That doesn’t mean it’s a bad idea, just a little impractical.

    The point that Ian brings up about being able to set a breakpoint is also very good. This leads to the question of is the debugger advanced enough to determine when a field on a class is set (whatever it’s accessiblity is) and break on it? If not, it should be. The design of the class should not be overly influenced by the tools that you need to diagnose it (this would be a good case).

    While the point that you make about people using properties everywhere is a good one (class boundary and visibility), good design pretty much makes this a necessity. Good design is going to promote the reuse of components outside of where they are defined, which will demand the declaration of properties. Also, the majority of time, the developers are exposing public properties on public classes (this is probably one of the most common class/member accessibility combinations if not the most), so the practice of always using properties just eminates from what people are doing most of the time anyways.

    However, if you have classes that have private or internal accessibility, then I would say that this is very, very applicable (if you don’t need to perform processing on the value).

    The one thing you don’t want happening is people exposing public fields because they get too lazy to write a property (I personally find it to be a pain in the a$$, after writing the property, the documentation, etc, etc). This is where good tools come in, features in the IDE to auto-generate the code/comment block, etc, etc.

    Finally, for some reason, I seem to remember reading somewhere that publically exposed fields on publically accessible types are not CLS-compliant. If this is the case, then this conversation is moot, as I don’t think you should be developing code that is not CLS-compliant (I’d hate for the VB crowd to miss out on my components because I expose a property with a type of sbyte).

  6. Keith Patrick says:

    Chalk me up as one of those who *always* uses properties. The only time I ever use fields is in a corresponding property. There are several reasons. First, I guarantee that any constraint checking, validation, initialization (yeah, I know this breaks an FxCop rule about processing within a property, but my property inits are lightweight) is uniformly enforced, regardless of who is doing the setting. Also, I can set a single breakpoint for a variable change (IBM VisualAge had a breakpoint condition you could set for when a var changed value, but I could never get it to work reliably; I’ve never gotten a VS.Net breakpoint condition to work, but I haven’t sat down to figure out why). Additionally, I *do* think that it improves readibility, as it places all variables that should be accessible in a single place. That being said, I have a Properties region that is broken up into visibility as well to keep things organized a bit more hierarchically.
    Out of all of them, though, my primary impetus by doing this is for maintenance, as all paths to a field flow through a single, well-defined and controlled point (oh, yeah, I value this over performance, so I don’t care much about the expense of calling a method rather than setting a field)

  7. Keith Patrick says:

    Kevin, it could be implemented via attributes (assuming a different means of intercepting the underlying set method than ContextBoundObject…I’m starting to run into some limitations with using it for something like this). Doing it that way (but again, there has to be some means of interception) would remove the need for language modification….use the attribute for storage instead.

  8. Personally speaking, I always use properties and never public fields. Why? Because my setters mostly tend to have some kind of pre-condition code in them to verify the validity of new values. This coding pattern has caught problems for me on numerous occasions, even when I was the only consumer of the class. It enables me to write and forget: The class becomes a black box at that point. (Bias note: I used to write class libraries for a living.)
    Now, I can see that in a TDD-type development environment, this isn’t so necessary any more for internal classes (after all, if your tests pass, you can’t be passing bad data to an instance of an internal class). However, when performing the required refactoring step in TDD (to remove a code smell), it’s possible that the internal class might become published, or some code is made publicly available, etc. Of course, in TDD, you shouldn’t write code until you need it, but I also subscribe to Design by Contract which tend to conflict a little.

  9. Colin Savage says:

    The "Improving .NET Application Performance and Scalability" project on gotdotnet : http://www.gotdotnet.com/Community/Workspaces/Workspace.aspx?id=540f8bd7-be95-45f7-a477-919d23294553
    Indicates in their "07_Perf and Scale – Improving Managed Code Performance.doc " that you can add explicit code access security checks to your property accessors. Just another consideration.

  10. Colin Savage says:

    While we are on the topic of properties, the biggest gripe that I have with the properties syntax is the inability to have different access modifiers for the get and set. Readability and maintenance would IMHO be much simpler than having to create a setMyProperty method with different access modifiers to the get.

  11. Scott says:

    The biggest problem I run into with using public fields vs. properties is with data binding to controls.

    Apparently the databind methods reflect over the object and look for properties rather than just public fields. The error that’s returned at runtime is, of course, obtuse. Something like "object foo does not contain a member named nameOfThingYouAreBinding".

  12. Trey Hutcheson says:

    I always use properties, with one exception ( structs/udts ). There are several reasons, including data validation. But my biggest reason in using properties instead of simple field access is the fact that you can notify other objects about changes in state via events or virtual BeforeChanged and AfterChanged methods ( for child classes ). This is huge for me personally. I guess a secondary reason could be versioning. If I wanted to add change notification later, I would have to change the signature from a field to a property. Bad.

    trey

  13. Chris says:

    I just think properties look pretty.

  14. Sunil Vishwas says:

    Consider using read only public fields:

    As the various experts already said so much there is litter room to express any additional thoughts. Some of us may agree that software engineering is more of an art than a science. I fully agree with both the side and would like to take a moderate approach.

    I would recommend using properties when there is any reason for protecting its data. For example:

    – Data is modified from one or more places; this may not be a big issue for the single threaded applications.

    – Validation or some action is required every time the data is accessed.

    – Data is stored in different type or format than its access type or format.

    – Data value may change from one read to another.

    – Data is accessed through UI where it is exposed through reflection using the properties.

    For rests of the cases where there is no apparent need to protect the backend data I would use read only public fields. While setting the field values through a constructor all sort of validation checks and computations can be performed. Once value is set as it nature there is no further need for modifications and validation and hence no need to protect it. As the field is read any modifications to its value is not possible.

    I am convinced with this theory and practicing it for more than two years. If you find any caveat then please let me know. I will be glad to update my theory.

    Thank you,

    SunilVishwas@HotMail.Com