Share via


Accessing private fields through properties...

(Writers note: I apologize for this C#-related post. I'll return to posting trivial and useless information, reviews, and links soon)

A post on one of our internal groups came up asking whether a class's implementation should use properties on that class, or whether it should restricted to fields. There was a bit of discussion, with some replying "sure", and others saying that you should always use properties.

Here's my take on it. The discussion is about a class that implements lazy loading of a bitmap property named "Bmp".

<soapbox>

 

If you use properties for everything, you're complicating the life of the code maintainer considerably. Instead of being able to trust that "bmp" has behavior that I understand (ie it's a field), I have to go look at the definition of Bmp to see what's going on.

 

In my book, that's an example of premature generalization - you're using a property *in case* you want to change things later. Premature generalization, like premature optimization, is something to be avoided. Or, as the agile guys would say, "You ain't gonna need it" - you're wasting time and bloating your class.

 

An exception to this is if you think you are going to version the class and client separately (ie you're building a reusable library), and you wouldn't be able to add in a property later.

 

If you use properties from inside your class when convenient - such as a lazy load of an bitmap - you're still making things tougher on the maintainer - the difference between bitmap and Bitmap is pretty subtle, especially if you don't have a naming convention for fields.

 

If you're in that situation, I think it's a far better solution to pull the lazy-loading code out of property and create a function named "GetBitmap()", and use that function from inside the property and in other cases where you need the bitmap in your class. It's more readable.

 

</soapbox>

Comments

  • Anonymous
    September 19, 2005
    The comment has been removed
  • Anonymous
    September 19, 2005
    I'm finding more and more that I am using properties to set initial values in constructors (either from constructor parameters or otherwise). The reason I am doing this is that I have side-effect code in the set accessor that I want to run when the value is assigned in the constructor. So I would say these sorts of cases would be best handled by having properties.

    I'm not sure why using properties would make life more difficult for a maintenance programmer. If you consider the possibility that in some cases you might want to use properties, and other cases, you might want to directly access fields, then when programming or maintaining a class, you have to think about whether to directly use the field or accessor each time. Maybe always using an accessor is easier in that case? What do you think?

    Also, with the awesome refactoring tools built into VS2005, encapsulating a field into a property is such a painless operation, that I can't really see the practical value of always doing that up-front, except for cases like the one I described above.
  • Anonymous
    September 19, 2005
    Haacked,

    You had me going there...
  • Anonymous
    September 19, 2005
    Tzagotta,

    Perhaps I can explain a bit more clearly.

    When you're doing maintenance, you spend a fair amount of time reading through code, trying to discover or (if it's your own code) remember how something works. In doing so, you need to keep a lot of possibilities in mind - does it do x? does it do y?

    To the extent that you can constrain the things that you need to learn to understand a class, you make it easier for that class to understand.

    That's the argument, though you don't have to agree with it.
  • Anonymous
    September 19, 2005
    Deja-vu?

    I'm sure I've read a blog post from you 18 months ago which talked about using public fields rather than go to the hassle of creating properties with private storage.
  • Anonymous
    September 19, 2005
    I have a dislike for unexpected side-effects - so have a personal rule that any object which can be changed post-creation must also raise an event to say that that change has occurred - the corollory being - don't create objects that are changed post-creation!

    But, for brevity and maintainability I've started using public fields instead of properties - the magic is the readonly field:

    public class Employee
    public readonly string FirstName;
    public readonly string LastName;
    public readonly Date Birthdate;
    public Employee( string name, string lastName, date birthdate)
    {
    Ensure.NotMissing( "firstName", firstName );
    Ensure.NotMissing( "lastName", lastName );
    Ensure.NotMissing( "birthdate", birthdate );
    FirstName = firstName;
    LastName = lastName;
    Birthdate = birthdate
    }
    }

    Not too much can go wrong with that - and I find it very quick to make and easy to read.
  • Anonymous
    September 19, 2005
    The biggest elephant you folks are missing is binary compatibility. If you have a library that exposes something as a field, you can't change that later to be a property.

    If there's any chance that an already deployed version of the library exists in the wild along with clients that reference the field, changing it to a property is going to break those clients, especially if the library is in the GAC (which can still be desirable, for updating reasons).
  • Anonymous
    September 20, 2005
    The comment has been removed
  • Anonymous
    September 20, 2005
    barrkel - oops... you're right of course. If it's in the wild you're out of luck.
  • Anonymous
    September 20, 2005
    Barrkel,

    I did say that there's an exception if you're building a library that you need to version separately. I think both of those are important - there are many libraries that always ship as a unit with their clients and/or for which a recompile is not an issue.

    Eric