Tuesday, August 30, 2011

Properties or Fields?

There was a great conversation on Twitter today about properties and fields. The discussion was about whether it makes sense to expose variables as fields and not bother with the overhead of properties. After all, it's quick and easy and you can always change it later, right? One participant suggested there could be design "assumptions / deficiencies / violations / smells" from using properties instead of fields, and someone else pointed out that the intermediate language, or IL, for properties is larger and will take more nanoseconds to process.

So what's the word?

First, I'll make a call to action for you to use the comments section below because I'm curious if anyone has ever had an issue with an application because their properties were too slow. I'm not talking about a property that fires some exotic validation routine that performs asynchronous server operations and crunches numbers approaching infinity before completing. I'm talking a simple property with a backing field and possibly a property change notification. It's highly unlikely the few extra IL codes or nanoseconds spent ever presented any tangible problems just because the implementation was a property and not a field.

So what does the property buy us?

First, it's important to note that just because a property looks like a field to the outside world doesn't mean that it is interchangeable. Changing a field to a property is a breaking change and requires all of your code to be recompiled. That's an expensive operation, and one that should immediately call out to the advantage of using a property from the start. Even though the language allows properties and fields to appear the same, the underlying IL is different. Consider the code to access a field:

ldfld string [MyExample]MyExample.MyClass::SomeVariable
Compared to the code to access the same "field" when it is exposed as a property:
callvirt instance string [MyExample]MyExample.MyClass::get_SomeVariable()

As you can see, the property provides the language convenience of looking like a field but underneath is still a method.

Personally, I believe the best description of the benefits of properties is in Jeffrey Richter's CLR via C#. Chapter 10 covers properties. I obviously don't want to reveal too much because every serious developer should have this book in their library, but I'll summarize a few key points:

  • It's easy to corrupt a field because there is no validation whatsoever (Jeffrey gives the example of assigning a negative age)
  • Properties provide data encapsulation
  • Properties have the benefit of allowing data to be validated and cleansed, and can throw exceptions when something is wrong
  • Properties can perform other actions such as interacting with a cache or triggering a notification
  • Properties can participate in data-binding, fields cannot

Jeffrey's book goes on to make several very insightful comparisons between properties and fields to help you determine the pros and cons for your particular situation. The bottom line is that good design choices are seldom related to reducing the number of keystrokes to complete a class. There are many factors involved and while it is a bit more code to expose a public property, I tend to follow Jeffrey's strong suggestion that all fields should be private, and access to them restricted through methods. Properties have the dual advantage of being special-purpose methods that can perform several tasks when obtaining or presenting a value, while presenting themselves with an interface that looks like a simple field.

Jeremy Likness

24 comments:

  1. I am definitely anti-public-field. You've done a good job of debunking the argument that trivial properties are indistinguishable from public fields. I'll go one step further and say that even trivial properties are an anti-pattern.

    I very rarely have a property that does nothing but access a field. Usually my properties follow one of these patterns:

    1. A read-only property whose backing field is initialized in the constructor.
    2. A view model property which passes through to the model, often transforming the value. (I don't store data in the view model.)
    3. A model property with change tracking. (Independent in Update Controls.)

    The only time I have a trivial property is when creating a serializable DTO. And I try not to do that very often.

    Years of experience have shown me that trivial properties rarely occur in practice. And when they do, it's in a pattern that should be avoided. And so it baffled me when Microsoft introduced the auto property syntax {get; set;}. Why put a shortcut in the language that's only useful for an anti-pattern?

    Avoid trivial properties, and eschew public fields.

    ReplyDelete
  2. Even if you're just exposing trivial properties you have the advantage that there is only a limited number of places that the field the property encapsulated can be accessed. When putting in debugging code this can be invaluable, as you can't directly debug field changes.

    Additionally, properties allow you to put field initialisation in the get, so that if it hasn't already been set by another process, it can be initalised to a default value (e.g.
    property pageTitle as String
    get
    If _pageTitle is nothing then _pageTitle = "default title"
    return _pageTitle
    ...
    )

    ReplyDelete
  3. Something in your header should have said c#. As it was, the topic is also important to other languages, and could have been generalized to any OO language.

    ReplyDelete
  4. I generally prefer properties as well; but fields do have one advantage. You can pass them as ref/out parameters to a function directly. Properties need a temp variable as a shim in order to be used.

    ReplyDelete
  5. Why are you asking for opinions? Why not write a simple test program that toggles a property 1000 times then changes the field directly 1000 times and compare the elapsed time of each process. That will end any debate, one way or the other.

    ReplyDelete
  6. @Malgrim, good point. The blog *is* called C#er : IMage but I agree for external facing links/articles I can be more explicit - thanks for the feedback.

    @Anonymous, that was more "tongue-in-cheek." I wanted to call out that likely you won't meet anyone who has run into this issue because it's so small. To me, writing code that hits a property 1,000 times doesn't tell me anything unless my application also hits it 1,000. If my applications hits it once or twice, I'm far more concerned about readability, usability, and maintainability of the code than I am saving 50 nanoseconds on an internal call.

    ReplyDelete
  7. First to answere the impact of properties vs fields vs methods: The CLR, in .NET anyways, does an amazing job in compiling the code and a property is compiled as one or two methods (depending wether you have get and set defined). Properties vs Method is identical in speed and compiled code. Now, properties vs fields, i dont there is a noticable difference, maybe if the fields are static, because the JIT compiler doesnt have to lookup any inheritance and go straight to the type declaration code in memory.

    That said, I dont think its a question wether to use properties or fields, because the answere is of course, properties. Now the big question is: properties or methods. Should you not use properties and define explicit methods about getting and setting private variables, or lean towards properties?

    Microsoft has answered this implicitly, by giving us short properties syntax get;set; By doing so, Microsoft has told us that properties SHOULD be kept simple as possible, and if you do need to perform much checks and lookups, then do so in a method.
    By defining an explicit method for getting a private field, you are telling developers that there are some business logic performed in the background and might not be thread safe.
    Whenever I see a property, I always think of that as an easy way to get a field, and no heavy performance loss. However, a method on the other hand is usually more demanding.

    ReplyDelete
  8. Dan Neely:

    "I generally prefer properties as well; but fields do have one advantage. You can pass them as ref/out parameters to a function directly. Properties need a temp variable as a shim in order to be used."

    It's precisely *because* you can pass them as ref/out parameters that I don't use public fields. If you later change the field into a property for some reason, you have to make changes in all the places where you pass the field as ref/out parameter.

    ReplyDelete
  9. Good post. I am currently reading CLR via C# (on chapter 8). I love this book!

    ReplyDelete
  10. I see it as the old lack of willpower debate. "I want yummy cake but don't want to bake or pay for it."

    Programmers using object-oriented design should NOT complain about writing object-oriented code. It's our job; stop rationalizing shortcuts.

    If nanoseconds are important then write monolithic code, or perhaps go native.

    ReplyDelete
  11. Exposing public properties with an internal backing field should provide you performance and security.

    ReplyDelete
  12. The problem with an issue like this is that there should be no "rules" as to using one vs the other.

    What you really want to do is understand the benefits to using Properties and if those benefits are required by your class, then Properties are the way to go. If you've thought about it and none of the benefits apply, then expose the field.

    Above are listed great points about properties and I've no doubt that the book lists many more. I likely use Properties over public fields 98% of the time. That being said, I've definitely created a few very useful classes with a lot of public fields and have not had any problems.

    One of the biggest problems in our (software development) industry comes from people blindly applying rules without any clue as to why the guideline (I'm not much for rules) is there.

    Think! Understand! Code accordingly!

    ReplyDelete
  13. We're lucky to live in a time when hardware allows us not to worry about performance as much as we used to.

    For what it is worth, in a simple loop that retrieves and then assigns a value, properties appear to take three times as long as fields. Then again, as Jeremy suggests, I have to loop 10 million times to notice a one-fifth of a second difference.

    If you are doing graphic intensive work involving lots of loops, a small performance boost from using a field rather than a property could probably come in handy. For standard LOB work, it probably doesn't matter as much.

    ReplyDelete
  14. Everyone makes a great point here. And let me bring it into focus: when you are developing graphics-intensive software, using XNA for example, the guidance is to use value types over classes (structs) and expose fields rather than properties. This is a case when the processing IS important and therefore the distinction must be made. And I also agree that there are no hard-and-fast rules - the chapter I alluded to in Jeffrey's book for example has pages of bullets comparing and contrasting to help you, the developer, decide what makes the most sense. Also keep in mind the difference between internally consumed classes vs. externally exposed APIs, etc.

    This is a great example of what some people consider are "textbook questions" in interviews but in reality strike at the core of quality software design and reveal whether someone is just slinging code by copying snippets from blog posts and articles, or has taken the time to learn the underlying framework to understand why they are going with a certain paradigm.

    ReplyDelete
  15. To me, it's a trade-off. Usually use properties, and never had an occasion where property overhead seemed to matter. But then, I've never (and I've been programming since the 70s) had to convert an field to a property either, so I don't see this as a deal of huge importance.

    If you are developing a public API, I'd say go with the property pretty much every time (there might be exceptions for extremely low level work).

    If you are working on high-level code, you'll probably go with properties because that is what feels comfortable to you ... but if you go medieval on some other programmer because they used a field rather than a property in a scope where it didn't really matter (and there are plenty of them) you are just being a jerk.

    ReplyDelete
  16. Okay, I'll play devil's advocate and pull out some Eiffel-like purist perspective: why have either fields or properties, shouldn't the implementation be completely hidden? l-values, who needs them, why not just do everything via set and get functions? (To be honest, in VB6/VBA at times I did take this perspective, since w/variants VB6 could be fickle with passed references (similar to the comment above on out params).

    ReplyDelete
  17. I'm definitely in the camp that uses Properties over Fields. However, I disagree with Michael L Perry about simple properties being an anti-pattern.

    Quite contrary to his assertion, I use auto-properties frequently. They give the advantage of being a Property, and thus available to those frameworks that use them, and being concise.

    When I want a property that is set in the constructor, and is public to see but private to set, I use "public MyProperty {get; private set;}" and everything is fine.

    Generally, even if you do have a private field, one should not use it directly unless absolutely necessary. Rather, use the property access. Given this, why have the extra cruft when it isn't needed?

    In my (many) years of experience, I've found "trivial" properties to be quite useful. In fact, good object oriented design has few hidden side-effects. I consider a "property" that also launches one or more operations or state changes in its setter to be a code smell. Useful if necessary, but best used sparingly. The more "magic" I encounter, the less comfortable I am.

    ReplyDelete
  18. @Anonymous: "[...] Microsoft has answered this implicitly, by giving us short properties syntax get;set; By doing so, Microsoft has told us that properties SHOULD be kept simple as possible, and if you do need to perform much checks and lookups, then do so in a method.[...]"
    I don't agree with your statement. The reason MSFT introduced "public T MyProp{get;set;}" was that a lot of properties doesn't do anything else (thats because MSFT encourages developers to use properties instead of public fields).
    Writing a method to get/set doesn't make sense at all since cases where validation took a long time are rarely seen (one should consider the app design in such cases) and as Jeremy pointed out, properties become methods in MSIL. There is a nice feature called XML/API docs that can be used to inform any user of your property that it might take a millisecond to get/set the value or that it isn't thread safe (thread safety is btw easy to implement when working with properties).

    ReplyDelete
  19. That this discussion would even take place reveals the sheer number of people discussing design who have little to know understanding of OO concepts.

    If the size of the IL or speed of a simply property are an issue, then you are probably doing it wrong. The other option is your using the wrong tool for the job.

    .NET is a wonderful tool for many application scenarios. But it was never intended for real time situations. And trying to make it work is setting up for spectacular failure.

    Two things come to mind in this:
    1) I would not hire someone who thinks using a public field is a good idea.
    2) I would not work for someone who thinks using a public field is a good idea.

    Such people really need to take some time and learn more about programming.

    ReplyDelete
  20. When I'm making a library that gets a separate project and could be used in multiple programs, I never use public fields.

    When I'm adding functionality to a large program or building a program I expect to get large, I don't use public fields.

    But when my whole program is 200 lines, there's no way in hell I'm going to make it 300 just to improve encapsulation.

    ReplyDelete
  21. my rule. excluding public facing APIs. just use fields.

    http://simoncropp.posterous.com/consider-using-public-fields-instead-of-prope

    ReplyDelete
  22. Having read Jeffrey Richter's book through, I respect his opinion about properties, however for me the arbiter in this case is StyleCop and StyleCop directs the use of Properties instead of having public access to fields.

    ReplyDelete
  23. This discussion is entirely worthless without setting a context.

    For immutable values, messages or the general data transfer object, public (and preferable readonly) fields are a proper choice. Here the coupling is defined by data. Interestingly, complex processing of data objects often requires the best performance possible.

    For services or the usual stateful class, only properties should be used, if any at all. Services should be coupled via interfaces (you can not put fields into interfaces). But even here, properties should be avoided if possible, because interfaces work best when they follow the "tell don't ask" principle.

    And if you are using StyleCop, you are lost in context-being-ignored-by-my-tool hell anyway. Try Resharper instead, it's much more gentle and does not force you to switch your brain off.

    ReplyDelete