A recent discussion about this spurred a bit of a debate. Ever since I can remember, I’ve always been told to keep fields private. If you want to expose them any more than private you should use a property. Of course, I was defending my stance on this and figured I should see what other people were saying. I turned to the trusty Stack Overflow (SO) for some answers.
Argument For: Control
One of the major categories of arguments for keeping fields private has to do with control. Some great points brought up by SO posters included that properties allow you to easily add verification to your data storage. With a field inside of your class, your control is over how this variable is manipulated is constrained to the class. As soon as you expose something outside of the class, you lose this control. Unless of course… you use a property to control the accessibility of this data.
Others added that without a property, there’s no easy way to know when a field changes. From the scope of your parent class, how do you know when a child class modifies your field? This is even more crucial when dealing with events–What if one day you want an event that fires when the value is changed?
One quote I really like from this post:
If now, or at some point in the future, any of your code ever depends on a field some certain value, you now have to add validity checks and fallback logic in case it’s not the expected value – every place you use it. That’s a huge amount of wasted effort when you could’ve just made it a damn property instead 😉
I don’t think I could state it any better.
Argument For: Abstraction
Another major point covered by most posters is the idea of an extensible API–introducing levels of abstraction. Specifically, that you should not neglect your child classes are essentially using an API when they inherit and have access to members that are more than private. There was even a comment describing it as fields “hurting opacity”, which is essentially the exact opposite of providing abstraction. The consumer of the API can see exactly how some data storage was implemented, and perhaps this is something you do want to protect.
One of the greatest points about abstraction that was mentioned is that by using a property, you can change the underlying implementation in the parent class without causing massive headaches in all the child classes. Using a concrete example, perhaps you used a property of type IList to wrap your Array field in your parent class. After your code is out and being used by all of your colleagues who have built child classes on top of your base class, you decide you could really benefit from switching to a concrete list class in your base implementation. Guess what? You’re in luck. All you need to do is modify the base class.
Using my above example, if you had used a protected field, you’d be exposing an array to everyone. You know what’s great about arrays? They use “Length” instead of “Count” for checking the number of size of the collection. If you switched your array field to be a List, you’d now be breaking all the code that was checking the length property of the array. Great.
Other Arguments For
I didn’t feel these arguments were necessarily core to my perspective on the matter, but I thought they were worth mentioning:
- There are plenty of tools out there that use reflection to check properties of classes (i.e. for things like serialization) that don’t operate on fields.
- “It’s so easy that there really isn’t a good excuse to not do it”. (I just thought this quote on the matter was kind of funny)
I felt that I had enough re-assurance from the rest of the C# community that this was the accepted practice. There are plenty of good reasons that clearly offer up some great benefits. And the drawbacks? The negligible performance overhead? The “code bloat”? Sure these for-arguments don’t apply in all scenarios (and this post does do an excellent job in offering the against-perspective) but in my opinion making it a “best practice” is setting yourself and your code up for success.