12

Here are some arguments for properties and my counter-arguments:

Easier to use than writing getter and setter methods

Getter and setter method pairs are a code smell. Making it easier to write these is like making it easier to fail a math test by using a Scantron form and filling in all 'C's. Objects that contain only state, for persistence, shouldn't be using getters/setters and should be creating immutable objects at the time of persistence.

What is important to a consumer of an object is what it does, not how it does it. Its behavior is what it does; its state is how it does it. If you find yourself caring about an object's state (except for persistence, though this also breaks OO), you're simply not doing OOP and losing out on its advantages.

They give a rough indication of performance to consumers

This is something that could change in the future, for any given property. Suppose in release 1.0, accessing PropertyX simply returns a field. In release 1.5, if the field is null, PropertyX uses the Null Object pattern to create a new null object. In release 2.0, the field is getting further validated by the getter method in PropertyX.

As the property gets more and more complex, the performance indication of using a property seems less and less truthful.

They're better than public fields

This is true. But so are methods.

They represent a fundamentally different aspect of an object than a method, and all consumers of the object should care about this

Are you sure that both of the above statements are true?

They're easier to type, man

Sure, typing myObject.Length is easier than typing myObject.Length(), but couldn't that be fixed with a little syntactic sugar?


Why use methods instead of properties?

  • No performance guarantees. The API will remain truthful even if the method gets more complex. The consumer will need to profile their code if they are running in to performance issues, and not rely on word-of-API.

  • Less for the consumer to think about. Does this property have a setter? A method sure doesn't.

  • The consumer is thinking from a proper OOP mindset. As a consumer of an API, I am interested in interacting with an object's behavior. When I see properties in the API, it looks a lot like state. In fact, if the properties do too much, they shouldn't even be properties, so really, properties in an API ARE state as they appear to consumers.

  • The programmer of the API will think more deeply about methods with return values, and avoid modifying the object's state in such methods, if possible. Separation of commands from queries should be enforced wherever possible.


So I ask you, why use properties instead of methods? Most of the points on MSDN are code smells in and of themselves, and don't belong in either properties or methods.

(These thoughts came to me after thinking about CQS.)

16
  • 5
    +1. Properties are methods with the syntax of fields and that just doesn't make sense. Mar 26, 2011 at 22:20
  • 23
    @Nemanja Trifunovic: It makes perfect sense if you have written type GetFoo() void SetFoo() ten thousand times. In all my time writing C# code I have never been confused by a property. Mar 26, 2011 at 22:35
  • 23
    Sounds to me like you've already made up your mind. What's the question? Mar 27, 2011 at 7:11
  • 9
    @Nemanja Trifunovic: "Getters and setters are generally bad" You can repeat that as many times as you like, but it won't make it true. How about explaining why you think they are bad? As far as SO crashes due to typing the property name instead of the underlying variable name, that is an impossible to miss error considering it will crash you program as soon as you call the property and it is pretty rare. When it does happen I know exactly what I did to cause it and I have it fixed in two seconds. I don't see the problem. Mar 27, 2011 at 21:35
  • 3
    Just passing by to point out to @NemanjaTrifunovic that that Why getter and setter methods are evil article is quite old, is about java and underlines a java weakness: the weakness of not having properties. (hence showing off too many implementation details) …biting our tail here. (it should be titled getters and setters are bad in java, cause we have no goddam well thought standard about those)
    – ZJR
    Sep 30, 2011 at 1:22

10 Answers 10

46

Why is it "methods against properties"? A method does something. A property is, well, a member of an object. They're totally different things, although two kinds of methods commonly written - getters and setters - correspond to properties. Since comparing properties with methods in general is not meaningful, I'll assume you meant to talk about getters/setters.

Getter and setter method pairs are a code smell.

Not necessarily, I'd argue, but either way this isn't a matter of getters/setters vs. properties but a matter of whether either should be used. Also note that you can e.g. leave out the setX part just like you can make read-only properties.

What is important to a consumer of an object is what it does, not how it does it. Its behavior is what it does; its state is how it does it. If you find yourself caring about an object's state (except for persistence, though this also breaks OO), you're simply not doing OOP and losing out on its advantages.

A highly questionable attitude. If the GUI wants to output data held by a DataStuffManagerImpl, it needs to get that number from it somehow (and no, cramming half of the application into the widget class is not an option).

As the property gets more and more complex, the performance indication of using a property seems less and less truthful.

[Methods have] No performance guarantees. The API will remain truthful even if the method gets more complex. The consumer will need to profile their code if they are running in to performance issues, and not rely on word-of-API.

In almost all cases, all the validation logic etc. is still effectively O(1), or otherwise negible in cost. If not, perhaps you've gone too far and it's time for a change. And a getX() method is usually treated as cheap as well!

Sure, typing myObject.Length is easier than typing myObject.Length(), but couldn't that be fixed with a little syntactic sugar?

Properties are that syntactic sugar.

Less for the consumer to think about. Does this property have a setter? A method sure doesn't.

"Is there a setter for this getter?" Same difference.

The programmer of the API will think more deeply about methods with return values, and avoid modifying the object's state in such methods, if possible. Separation of commands from queries should be enforced wherever possible.

I'm not sure what you're trying to tell us here. For properties, there's an even stronger unwritten law not to cause side effects.

8
  • 3
    +1, And its not an unwritten law. Property usage guidelines on MSDN has it written with many others. I think OP should go through them to make himself clear of many doubts. And I can't post a link here since I am writing this from my phone, but guidelines should be easy to find.
    – decyclone
    Mar 27, 2011 at 10:05
  • @delnan: Properties are not that syntactic sugar. Properties can be treated like fields (they can be used as an assignment target, if they have a setter). Methods cannot.
    – xofz
    Sep 30, 2011 at 20:11
  • 1
    @SamPearson: obj.x = y maps to obj.setX(y) and obj.x maps to obj.getX(). How's that different?
    – user7043
    Sep 30, 2011 at 23:09
  • 1
    @SamPearson you can change the visibility of a property setter and getter independent of each other. I use this all the time with my Entity Framework objects: my setters are protected (so only the framework can set a value). So it's perfectly viable to say int length=myObject.Length without allowing myObject.Length=10 Mar 14, 2012 at 20:13
19

Getter and setter method pairs are a code smell.

That is a faulty assumption and completely incorrect. Get/Set methods are a way to encapsulate a data member and are in no way a "code smell". I really hate the way some people throw around the term "code smell", but anyway...

This is something that could change in the future, for any given property. Suppose in release 1.0, accessing PropertyX simply returns a field. In release 1.5, if the field is null, PropertyX uses the Null Object pattern to create a new null object. In release 2.0, the field is getting further validated by the getter method in PropertyX.

As the property gets more and more complex, the performance indication of using a property seems less and less truthful.

Sounds like a poorly designed API, I don't see how that is the fault of property syntax.

Properties in C# were simply syntactic sugar for a very common pattern that made our lives as programmers a bit easier. However, these days, if you want to use data binding you "must" use properties, so they are now a bit more than syntactic sugar. I guess I really just don't agree with any of your points at all and I don't understand why you dislike a language feature that directly supports a common pattern.

7
  • 1
    I'm going to give a bounty to come up with a better term than code smell. Just read a book on refactoring where it is used about a thousand times. It's like fingernails on a chalkboard.
    – JeffO
    Mar 26, 2011 at 22:33
  • 1
    @Jeff O: Yeah, I find that the people who seem to throw that term around the most typically don't have a lot of experience. Mar 26, 2011 at 22:36
  • 6
    @Jeff O and @Ed S: IME, "code smell" has become the go-to term that people use when they really mean "I don't like it, but I don't actually have a reason" Mar 26, 2011 at 23:18
  • 3
    @SnOrfus: Yep, or when they hold "religious" views that often make little sense in practice, like "a method should never have more than X number of lines", which in turn is usually just a repetition of something they read somewhere. Mar 26, 2011 at 23:49
  • 1
    The inappropriate use of getter/setter methods is a code smell, but so too should be the inappropriate use of anything. Even when things have narrow use cases, employing such things for those use cases should not be considered a code smell. The creation of setters for everything shouldn't be a blind habit, but one shouldn't be afraid to include them when appropriate. What's necessary is to balance the usefulness to clients of being able to change state, versus being able to find out in future what the state was earlier (easy if state is immutable). Both are useful, but code must pick one.
    – supercat
    Feb 24, 2014 at 16:47
10

Your premise is wrong.

Properties are in no way a contract to performance or internal implementation or whatever.
Properties are special methods pairs, that semantically represent an attribute, if you will. And thus the only contract is, that a property behave as you would expect an attribute to behave.
If I ask for an object's color, I don't make assumtions whether it is obtained by a plain field access, or whether it is calculated just in time.
The whole point is, to have the ability to expose the behaviour of an attribute by using methods, while it is transparent to the consumer of the interface, whether you're using a field or accessors.

Having attributes (and actually hiding their implementation, as properties do opposed to fields) is a powerful declarative feature, that is the basis for having visual object inspectors and other automatic view generation, for data binding and many other useful things. And most importantly, it clearly transports this information for your fellow programmers as well.

6

Another important reason in my book for using properties is that they can increase readability greatly.

account.setBalance(Account.getBalance()+deposit);

is plainly much less readable than

account.Balance += deposit;
3
  • 6
    Except that Balance shouldn't be a property because there is sure to be significant business logic associated with changing it (check for overdraft; charge service charge; record transaction, etc.) Your readability point is completely valid if applied to a different example (Temperature, BackgroundColour etc.) Mar 27, 2011 at 18:28
  • 9
    Why not account.Deposit(amount)?
    – xofz
    Mar 27, 2011 at 22:15
  • 4
    @Sam Pearson: +1. A perfect example of why getters/setters often indicate poor design. Mar 27, 2011 at 22:42
6

The consumer is thinking from a proper OOP mindset. As a consumer of an API, I am interested in interacting with an object's behavior. When I see properties in the API, it looks a lot like state. In fact, if the properties do too much, they shouldn't even be properties, so really, properties in an API ARE state as they appear to consumers.

A property is supposed to be a state. If the underlying setter or getter code changes to add significantly to processing required to set or get the state then really it's no longer a property and you should replace it with methods. This is up to you as developer of the code.

Putting too much (how much is too much depends) code in a setter or getter is wrong, but just because it's possible is not a reason to throw out the pattern in all cases.

6

One thing you are missing, and I don't know if this is due to ignorance or if you're intentionally overlooking this detail, is that properties ARE methods.

When you use C#'s property syntax, the compiler quietly creates getter and setter methods with metadata that tells languages that understand properties as a first-class syntactical feature to treat them as such. That is, in fact, the syntactic sugar you're asking for. A few languages that can be run on the CLR don't completely hide this detail from you (Boo, if memory serves me, and some Lisp implementations), and you can call the getters and setters explicitly.

Properties occasionally have side-effects, like triggering change notification events (INotifyPropertyChanged, for example) or marking an instance of a class as dirty. This is where they have their real value, though creating them is a little more work (except in Boo, which has syntax-savvy macros).

Now, the broader question is whether getter and setter methods are, in fact, A Good Thing. There are clearly tradeoffs; if you have mutator methods, your code is inherently less parallelizable, because you now have to deal with thread synchronization issues. And it's quite possible that you'll risk violating the Law of Demeter using mutator methods (whether called properties or getter/setter methods; they are equivalent), because it's so darned convenient to do so.

But sometimes it's the right thing to do. Sometimes your problem is to grab data from some source, change it a little, present the updated data to the user, and save the changes. That idiom is well-served by properties. As Allen Holub's article says, just because getters and setters have problems doesn't mean you should never use them. (Parroting abstract Guruspeak considered harmful). Even when you follow the Class/Responsibilities/Collaborators approach, you still end up exposing either information or presentations of information to somebody; the point is to minimize the surface area of entanglement.

The upside of properties is that it's very easy to have another object take advantage of them. The downside of properties is that it's very easy to have another object take advantage of them, and you can't easily prevent that.

Object mutation makes sense at the controller layer, in, for example, an MVC architecture. That's your collaborator. Your view is also a collaborator, but it shouldn't directly be mutating your objects, because it has different responsibilities. Rolling presentation code into your business objects isn't necessarily the right way to avoid getters/setters either.

The equation changes a bit if you use functional, rather than pure OO, abstractions, which generally makes making copies of a "record" object with a couple of changes pretty trivial, though not free. And hey, If you're trying to get performance guarantees, properties are generally more predictable than lazy rebuilding an immutable collection.

4

You have almost the opposite religious viewpoint to me :)

When I moved from Delphi to Java the lack of properties was a huge affront to me. I was used to declaring a property and either pointing it directly to a private variable or writing a (protected) getter & setter then "plumbing" them to the property. This encapsulated the property and controlled how it should be accessed in a clear unambiguous way. You could have a read-only property that calculated the total when accessed and call it "Total" not "_getTotal()" or similar ballochs. It also meant that you could restrict access to properties by making them protected in the abstract base class then moving them to public or published in subclasses.

To me, properties are a more natural & expressive way of setting & getting the state of the object. Relying on unenforced coding conventions is more of a "code smell" than anything you're criticizing properties for. Also, as others have said, coming up with a badly designed use of properties and using its failings to try & dismiss the concept of properties in general is extremely bad form. It's possible that you've only seen bad use of properties & assume that's the way it is I suppose but you should do more research before becoming too dogmatic.

2
  • +1 That indeed a real use of a property. Great answer. "It also meant that you could restrict access to properties by making them protected in the abstract base class then moving them to public or published in subclasses." Jan 23, 2012 at 5:43
  • Delphi misuses properties ad nauseam. You don't sort list, you set its sorted property to true. So setting it to false gives you the original list. :D Or does it shuffle it randomly? :D Or whatever, it's just stupid. Additionally, it's damn slow compared to a proper sorted set. Properties aren't bad, but I've learned to use them very sparingly (till the point of being quite happy with getter and setters; I'm using mostly Java).
    – maaartinus
    Jul 30, 2017 at 23:13
1

One of the reasons properties were introduced in the Java Beans Framework was to allow integration with an IDE - you can drag those components to the IDE and edit the properties using property editors.

(back then they were only regular getters and setters - and were defined only by the naming convention - and this did indeed smell)

Today there are even more cases where properties are accessed and modified not through regular code - such as while debugging.

1

One other angle -- they really came from VB. Remember, back in the dark days of the 20th century when .NET was conceived one major emphasis was it was an easy, drop-in replacement for VB so your VB programmers could just drag and drop things onto webforms. VB had properties so you needed to keep that feature for things to translate right.

1
  • 1
    Anders Heljsberg designed C# (and some of the IL) and also designed Delphi - which had properties. Sep 30, 2011 at 1:51
1

There are at least two purposes for properties:

  • They are conceptually identical to fields even if they're implemented differently. A getter should not change the state of the object and should have no side effects. A setter should only change the state in ways conceptually similar to modifying a field and not have other side effects.

  • They're syntactically identical to public (possibly read-only) fields. This means a public field can be changed to a property without breaking callers at the source level.

3
  • Yes, but note the word "should". There is nothing about properties that prevents getters from having side effects and in fact I've seen numerous cases where that was the case. Mar 27, 2011 at 20:53
  • 1
    Changing a public field to a property will break binary compatibility, the consuming code will have to be recompiled - although not modified which I'm guessing is what you were getting at :)
    – MattDavey
    Sep 28, 2011 at 15:35
  • @MattDavey: Thanks. That is what I meant. Edited.
    – dsimcha
    Sep 29, 2011 at 22:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.