Properties? Not my bag, baby.


Eric recently posted a blog: “Property or backing store from inside a class?”, and I responded in a way that skirted the issue entirely.  I want to discuss them in a little more detail.


 


Part 1: Why bother?


 


First, why do we use properties?  The most common answer I hear is “future-proofing”.  Specifically, people are concerned that they may need to change the behavior of a property, and don’t want to break existing consumers. 


 


I understand the concern, but I don’t subscribe to the practice 100%:



  • YAGNI – Most of the properties I write, I won’t need.  They just go to waste.  It’s PrematureGeneralization.

  • I’ll probably build some other part of my API in a way that I have to break the contract when I update, so the properties won’t help.

  • If my class has default accessibility (internal), then it’s trivial to recompile every consumer, so no future proofing is necessary.

  • It takes a simple idea (a field in a class) and makes it take 6 lines.  This clutters my code.

  • It’s not the Simplest Thing That Could Possibly Work.

 


If you’re a library vendor, things are a bit different.  You’re selling upgradeability, as well as functionality.


 


Most of this is inspired by a blurb in Ron Jeffries’ article, Adventures in C#: Contiguous Owners, at the very bottom of the document.  He, in turn, was inspired by Ward Cunningham.


 


Part 2: a simple approach


 


Just use public fields.


 


Wait, doesn’t that violate Encapsulation?  Only a little bit.  If you say “I have a public property call Foo, and its type is int”, that’s not much different than “I have a public field call Foo, and its type is int”.  What are you encapsulating, exactly?


 


Wait, doesn’t that open a risk that someone might set the value, when they shouldn’t?  Yeah, but it doesn’t scare me much.  I rarely find myself writing code that manipulates the values in other objects.  It’s bad behavior on my part, and rarely necessary.  If it does happen, and it’s a problem later, I will fix it then.


 


Wait, I’m still worried about rogue setters.  Fine, use ‘readonly’.  I do:


 



        public readonly int Foo; // note that it’s named like a property.


 


        public C(int foo)


        {


            this.Foo = foo;


        }


 


Now Foo acts like a property with only a getter, and has the same syntax.  If, someday, I decide it needs to be a property, I don’t have to modify my consumers. (I do have to rebuild them if they’re in a different assembly.)


 


I now don’t have to worry about accidentally changing a value, even in my own code.


 


Also, I’ve noticed a certain pattern.  Typically my fields are either “identity of the class” or “working data of the class”.  I can see which is which by marking the “identity” fields readonly. 


 


Part 3: lazy load


 


Sometimes you want to calculate something on-demand, and then cache the value.  For example, you might write:


 



    class Size


    {


        public readonly uint Width;


        public readonly uint Height;


 


        bool _haveCalculatedArea = false;


        uint _area;


 


        public Size(uint width, uint height)


        {


            this.Width = width;


            this.Height = height;


 


        }


 


        public uint Area


        {


            get


            {


                if (!this._haveCalculatedArea)


                {


                    this._area = this.Height * this.Width;


                    this._haveCalculatedArea = true;


                }


 


                return this._area;


            }


        }


 


If you take this approach, you now need to be careful to use the property inside your class, to work with the correct semantics. 


 


I had said I would extract a new class encapsulate this behavior.  Here’s what that might look like:


 



    class Size


    {


        public readonly uint Width;


        public readonly uint Height;


 


        public readonly LazyArea Area;


 


        public Size(uint width, uint height)


        {


            this.Width = width;


            this.Height = height;


 


            this.Area = new LazyArea(this);


        }


    }


 


    class LazyArea


    {


        readonly Size _size;


 


        bool _haveCalculated = false;


        uint _value;


 


        public LazyArea(Size size) { this._size = size; }


 


        public uint Value


        {


            get


            {


                if (!this._haveCalculated)


                {


                    this._value = this._size.Height * this._size.Width;


                    this._haveCalculated = true;


                }


 


                return this._value;


            }


        }


    }


 


Note: I’m violating the Law of Demeter by exposing the Area as public.  Consumers must use “mySize.Area.Value”.  I think I should probably make it private, and use a public field:


 



        readonly LazyArea _area;


        public uint Area { get { return this._area.Value; } }


 


Part 4: Lazy<T>


 


I’m thinking I could write a generic class to implement this type of caching in a general way.  Do you want to take a stab at it, and post your result in a comment or on your own blog?

Comments (30)

  1. milbertus says:

    I’ve been thinking that public fields are the way to go over properties. My only problem with the readonly approach is that it makes the field readonly for code both outside and within the class. While I know there are cases where you can initialize a variable once and never change its value again, there are also times when members of the class need to change the value, while code outside of the class shouldn’t be allowed to. Sadly, the readonly approach doesn’t work in this case.

  2. jaybaz [MS] says:

    When you find yourself considering a property, try asking if there’s a refactoring to be done. See if putting the field + property behavior into a new class could make sense.

    Properties aren’t useless; there are times when they’re exactly what you want. But I think they’re overused today, to the detriment of code clarity.

  3. Sean Terry says:

    Food for thought, certainly. However, public fields don’t fit the bill for my needs. Data validation and security checks are common things I use in my properties.

  4. jaybaz [MS] says:

    Sean: In your situation, does creating a class to handle the validation and security make sense? Does it make cleaner, more OO code?

    (At this stage in my live, I’m in the more OO=better. I’m sure I’ll swing back sometime.)

  5. Paul Wilson says:

    Binding expects properties, not fields.

  6. I posted a lazy load class on my blog.

    I’m still downloading the technology preview so I haven’t checked the syntax yet, but it communicates the overall idea, and it should work.

  7. The WYSYG editor ended up interpreting all my "<T>"’s at tags. I had to switch to html view and then change escape out the "<" and the ">" and the corrected the problem. You should be able to view the correct code now.

  8. Chris J. Breisch says:

    Well, I can’t say that I haven’t thought of this myself. However, I think I’ll keep on using properties. Why? Because I like to be able to do foo.Property = value;

    And I like to be able to check for valid assignments in my setters. I suppose I could do it without a setter and use a method, but that doesn’t seem as ‘clean’ to me.

    Perhaps it’s becuase I write a lot of class libraries and you seem not to that I look at things this way.

    Also, setting your public fields to readonly seems very short-sighted to me. And I’m not talking necessarily about Future-Proofing my code. But in very few classes to I have a property/field value that can be set once and is never changed by anything again. Public field seems fine for that extremely rare occurrence, since you don’t need to worry about any logic for setting/retrieving.

    Now, if I’m using TDD, I might be able to create a field as public readonly in an early step, but it’s almost certain to change as I move on. I suppose I could always start with that, but I know I don’t want a public writable field, so as soon as I determine that it’s writable (which is most of the time) then I’d have to change that. Seems pointless to have to always keep doing the same refactoring. I’d much rather go ahead and make them be properties, and then if I determine later that that’s not necessary, I can refactor back to a public readonly field. Seems like this would be necessary much less often.

  9. Ryan Farley says:

    Paul mentioned this, but there are things to consider when deciding to use properties vs. public fields (as Jay also mentioned in the post). For example, if you choose to use public fields instead of properties then you better make sure that you’d never want to bind the object since you won’t be able to unless you use properties.

  10. Mikel Berger says:

    More info properties. This sort of extends on the topic Kyle covered in his article. In Jay’s post the read only situation was something I hadn’t thought of with sticking with the simpler public properties. But really, regardless of which method you use if you decide to go from a read/write to a read only you’re going to break something. Jay wrote a post entitled Properties? Not my bag, baby. When I first started writing C# code, I used properties for everything. But recently, I’ve felt that I was wasting a lot of time writing trivial properties. Yes, I know that in Whidbey I’ll be able to use expansions to write them easily, but that still means that I have to deal with the property bodies cluttering up my code. So, that got me thinking about whether it makes sense to be writing properties in the first place. After a bit of thought, here’s my current position: Properties are&nbsp;a great thing for component libraries. There are certainly cases where you would want the future-proofing and decoupling that properties gives you. But when you’re working on a single project that gets built all at once, I don’t think you’re getting any future-proofing benefits, and you have to pay the &#8220;property tax&#8221; the whole time. This may be heretical, since &#8220;use properties&#8221; has been the common guideline. What do you think? [C# Stuff]…

  11. Sean says:

    What about performance/GC concerns?

    This isn’t my area, but this question actually just came up..

    Will value = foo.publicField make the lifetime of foo dependent on value ifn foo falls out of scope (and value doesn’t)?

    versus

    value = foo.Property..

    Using public fields seems alot like a Mort line of thinking.. but if you’re in a Mort factory, why not 😉

  12. Shawn says:

    jaybaz said: "Wait, doesn’t that open a risk that someone might set the value, when they shouldn’t? Yeah, but it doesn’t scare me much. I rarely find myself writing code that manipulates the values in other objects. It’s bad behavior on my part, and rarely necessary. If it does happen, and it’s a problem later, I will fix it then."

    In my book, that’s a potential problem. Its better to code defensively than to take the attitude of "I’ll fix it later". I rarely expose a public field because more often than not, I end up needing to use properties for various reasons (granted, I usually write libraries and frameworks so perhaps we are in a different boat).

    I tend to think more futuristically and if I can foresee a potential expansion of its use, I’ll code appropriately. What do I do in those cases where I write all these properties and all they will ever do is wrap a variable that may just as well have been a public field? I write the property anyway. I personally, prefer to use properties anyway. However, I do often expose readonly properties and they have their use there, as well.

    I typically use the properties internally as much as I would externally. There are only a few instances where I operate directly on the field. Especially if my class might be inheritied, all the more I use the properties rather than the private members (unless there is a good reason and sometimes there is, but it is the exception rather than the rule).

    Thanks,

    Shawn

  13. jaybaz [MS] says:

    Chris says "I write a lot of class libraries and you seem not to that I look at things this way".

    My stated approach is that I’m always writing class libraries. Even when my final goal is an application, I want to create it by first creating the ideal class library for my application, and then having a very small Main() method.

    If I want to have verification in my setter, of course I won’t use a public field.

    But as long as I know I can rebuild all the consumers of the code I write, then I will only create a new property if it actually improves the clarity of my code.

  14. Just a couple of thoughts why I think it’s a good idea to actually use properties (mostly relates to ASP.NET):

    1. DataGrid-enabled Business Objects for ASP.NET

    While working with data, I like to encapsulate data from DBs into strongly-typed objects. If I use fields in my class, the (asp:)DataGrid object won’t be able to render the properties when AutoGenerateColumns=true.

    2. Caching

    When data is expensive to get, you want to cache it. Say you use an Application variable to that end. Since business objects are likely to be used by more than one control, it’s not very comfy to access the Application property directly (null? typos, etc.). My favorite approach is to encapsulate it into a property. Only with a property can you fill the cache if it’s empty without the user of that class having to take care of it.

    BTW, you can declare a property in one line 😉 C makes it possible

  15. jaybaz [MS] says:

    Maybe I’m being picky, but I think that caching isn’t the goal, it’s lazy creation.

    Here’s a lazy loader that encapsulate those semantics in a nice, OO way: http://blogs.msdn.com/jaybaz_ms/archive/2004/04/30/124229.aspx

  16. jaybaz [MS] says:

    Hmm, I think the article you pointed to is a bit inflamatory. For example, the reasons stated to never use structs are mitigated if you only use immutable structs.

  17. Sean Malloy says:

    I’ve been using fields as properties since day one.

    In an in-house project, where your team controls all the code, its easy to do.

    You can upgrade a field to a property late ron, if you need additional code wrapped around the get/set later on.

    Java can not do it. You eithe rhave the choice of public fields, or get/set methods, which means modifying all consumer code – PITA.

    C# allows you to upgrade fields on a case-by-case basis. As jaybaz points out, a public readonly field is effectively the same as a get property (Except you have to init the field at construction time…)

    Its just a nice path.. all public fields, save code.. upgrade necessary fields to properties as required… repeat.

  18. Funny, my feeling has always been that properties were one of the best things added to OOP since its early days.

    >> It takes a simple idea (a field in a class) and makes it take 6 lines. This clutters my code.

    That’s because C# was not implemented to streamline the definition of properties. If it was, this wouldn’t be an issue. So I say don’t confuse concept with implementation.

    However, I think one of the biggest problems is that Microsoft chose to implement fields as having different signatures than properties (ugh!) If you could define a field and later change to a property w/o affecting clients, there would be no need to define a property prematurely and use 6 lines of code when one would do.

    So, I think the designers of C# (and VB) caused this problem. And please don’t say that fields are different than properties for performance reasons because most of the time that doesn’t matter, and MS could have defined fields has having something like a "direct" qualifier that would cause them to behave like fields behave today when you someone really needs them to be super fast (but doing so would limit future compatibility w/properties.)

  19. Eric Gunnerson just posted Properties vs public fields redux… It’s no secret that I agree with Eric