Recently, one of the readers of Effective C# asked me some questions about Properties vs. Get and Set methods. It turned into a rather interesting conversation, so I'm posting it all here:
I'm writing because of a discussion we've been having about the first item in your book. As you know, that item says to "Always use properties instead of accessible data members."
Our main issue is that the book doesn't explain the value of properties over the traditional set/get method approach. In fact, some of the folks on the team are arguing that properties are just syntactic sugar that have more negatives than positives. One example given is that if a property has both set and get implemented then the property could accidentally be assigned when the intention was comparison
obj.serverDown = false
versus the desired
obj.serverDown == false
Whereas, with the traditional set/get method, the above bug isn't possible
I'm curious what your opinion/rationale is on the topic? Also, do you know of any other
references (online or in print) that discuss this issue?
There are a few reasons why I believe Properties are beneficial vs. the traditional get and set methods used in earlier OO languages (such as C++).
Properties are naturally serialized using the XML serializer. Therefore, a list of employees defined using properties becomes a simple XML document for wire transfer. (I’m assuming read/write properties for Name, Salary, etc). You can’t easily use the XML serialize for a similar type implement using get / set methods. This is a necessity to build SOA applications where the client will request a document from the server. The natural document is the set of public properties for a data type. (The same argument can be made for the client code, where a command document is a type with a set of public properties).
This one may be cheating, because one could argue that MS could implement databinding using get / set methods. But they didn’t, so properties are the clear winner here. And, in fact, if MS did use a get / set metaphor, it would be similar to Java beans, where get_ and set_ denoted a property. Personally, I dislike the idea that a methods name can give it magical behavior.
Despite the text in the article you reference below, I think there is merit to the property syntax, when used correctly. It clearly shows that a type contains certain data elements (at least logically, even if not physically). Point.X looks cleaner to me than Point.get_X(), or Point.set_X(256). The syntax of the language expresses the design intent more clearly. That’s certainly subjective, but that’s my opinion.
To address your concern below, there are two answers. First, it’s much less likely to make the mistake of if (obj.ServerDown = false) because it can only be done with boolean types (not any arbitrary integral type as in C or C++). Secondly, the habit of putting the constant on the left side fixes that as well: if (false == obj.ServerDown).
Let's consider this code:
public void Calc(int foo)
Sum = 0;
for (int i = 0; i < foo.Length; i++)
Sum += foo[i];
It is indeed possible that the Length property (or the indexer) cause serious inefficiencies. (Look at the code again, and imagine that Sum is a property with Get and Set accessors.) But, let's not get carried away. In most cases, the JIT compiler will inline simple properties, and there is no inefficiency at all. Of course, you may consider caching the temp variable anyway, and there may be some savings, if the setter has extensive validation.
Syntactically, you could hide anything inside a property's get or set methods. You could even include database access to retrieve (or set) the value. But, just because it's syntactically correct doesn't mean you should do it. I’d say it’s a bad practice to hide a database access behind a property for several reasons. Would you ever make a database call to retrieve one scalar value? (That’s what such a getter would look like.) Wouldn’t it be far more likely that you would design your application to pull some reasonable set of data from the database and have it locally available? My point is that I wouldn’t believe GetCommission() makes a database call any more than a SalesPerson.Commission property. And, if the app really does use some form of lazy evaluation, you’re paying the performance hit regardless of the property or method syntax, so it really doesn’t matter.
So, if the argument is that properties are ‘hiding’ performance issues, I don’t think that’s often true. Most developers would think getSomething() and setSomething() would contain the same code as a Something property. The JIT compiler knows a property is a get / set method pair and can perform the same optimizations as a get / set method pair. So, you really don’t lose anything. In some sense, properties are syntactic sugar (there’s no new amazing functionality here), but the XML Document serialization and databinding are the two practical reasons to prefer them over get / set methods. Your colleagues have found the one negative (= vs. ==), which has been around since the dawn of C, so we’ve probably got the habits to handle that one.
After that initial dialogue, the reader and I discussed some guidelines for deciding between properties and methods. Because, there are performance pitfalls hiding behind properties and indexers, if misused.
All of these projects are Open Source (using the Creative Commons license for content, and the MIT license for code). If you would like to contribute, visit our GitHub Repository. Or, if you have questions, comments, or ideas for improvement, please create an issue for us.