Jay and Properties…


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 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 “property tax” the whole time.


This may be heretical, since “use properties” has been the common guideline.


What do you think?

Comments (23)

  1. Daniel O'Connell says:

    Personally, I wish that the design of C# had taken properties a bit more into account and given us a simpler system to express them in the simple(and considerably more common) scenarios where they are nothing but simple wrappers. I know it is a tricky syntax to come up with, but it would be *alot* cleaner, for component developers and internal situations if you could easily write

    public property string X{get;set;}

    or just

    public string X{get;set;}

    I assume that such a construct was considered and thrown out for good reason, but it is something I’d like to see some day.

  2. Scott says:

    That’s fine, but it means that data binding and serialization (both XML and binary) break right?

    Reflection breaks too right? So all the code generators go out the window.

    Don’t get me wrong, I agree with the use of public fields instead of properties. But it seems to me that the time to decide this issue was long before now. We’re stuck with it and to change now would be pretty disasterous.

    Unless you mean, "Use public fields unless you have to use properties". That makes sense.

    Daniel: It seems to me at that point you’re just writing a public field but with some extra sugar. Maybe an attribute modifier would be a better choice?

    [property]

    public string hootie = "";

  3. Daniel O'Connell says:

    The definition of the syntax is tough. In the ideal case you would want to allow

    1) simple getset properties

    2) simple get properties with either a private set or a compiler generated direct field set(similar to how simple event invocations work)

    3) similar simple set properties with private or generated get code.

    4) the ability to apply attributes to that property. The above syntax implies that you define a field which the compiler generates a property for. This would make it hard to apply an attribute to that property, and certainly would make it impossible in an clean manner.

    While the attribute would work, it lacks a clean way to express granularity and it requires considerable modification to the expression if you decide to change the property. To express granularity, you’d end up defining enums and other bits of data which the langauge already defines as pseudo-keywords, and there is no way to fix the difference in expression. Also, I think Attributes are really overused and shouldn’t be used to implement language features.

    ALso, looking at it again, even with the attribute it looks like a field, not a property, and will be read as such.

    Each syntax I’ve looked at has one downside or another, I finally decided that the public string X{get;set;} approach made the most sense because of how similar it was to the exising syntax. It doesn’t allow for custom fields, but it does solve alot of the issues with properties, as I see them. The compiler generating the underlying field access is a possibile way to avoid the need for custom fields, although it has some issues(the accessor could be used as a ref parameter, for example, resulting in an assignment even though its supposedly a "get", etc).

  4. I know you said ‘single project that gets built all at once’ – but just to be clear and picky, you also have to make sure you never call that project from anywhere else or it becomes a real pain to change. Changing a public field to a property will your code’s interface, breaking any calling code, until that code is recompiled too.

    Personally it is rare that I’m sure code will never be used elsewhere one day… Maybe these preferences just come down to the types of projects one does. If you use code folding they are pretty much identical for scanning code (though I hate they way accessors need those extra clicks to unfold, ugh). Tthe main argument against using them seems to be ‘too much typing’, which sounds more like a syntax/ide problem than an inherent problem with properties, no? It is pretty easy to make a macro or codegen, not sure I’d sacrifice even a tiny benefit if that is the basic reason…

  5. FixIt says:

    Just support something like this:

    public Button CancelButton { set; get; }

    (maybe some extra keyword)

    now have the compiler to translate this to the following code automatically:

    private Button cancelButton;

    public Button CancelButton

    {

    set { this.cancelButton = value; }

    get { return this.cancelButton; }

    }

    I’m really wondering why this shortcut wasn’t supported in .NET 1.0 already.

    Whidbey C# now supports crazy geek toys like Generics but still no support for simple stuff like this 🙁

  6. FixIt:

    In VS 2005 C# you can type prop and press the tab key twice, and a property will be added with a private field, this will make it much easier and faster to add a property to the code.

  7. Sorry FixIt, I misunderstand you post, I read it like the IDE should automatically add the while property body with a private field. So please ignore my post.

    I like FixIt ideas about just add

    public Button CancelButton { set; get; }

    But this is a similar way of adding a property to an interface. So I think this could confuse developers.

  8. FixIt says:

    You could add a keyword:

    public Button CancelButton { set; get; auto; }

    or something like that.

    There is definitely a solution way of doing this easily.

  9. My wish for properties (and I’m not alone here) includes the ability to make get and set be differently accessable. More often than not, "get" would be public and "set" might be internal or private.

  10. Clinton Pierce:

    You can set different protection levels on set and get in C# 2.0

  11. Ryan Farley says:

    I agree with Scott. I use properties all the time – but that is mainly because of the chance that I might need to bind or use reflection with an object (etc).

    However, I *don’t* like the idea mentioned by some here about using something like:

    public Button CancelButton { set; get; }

    and have the compiler interpret that to mean:

    private Button cancelButton;

    public Button CancelButton

    {

    set { this.cancelButton = value; }

    get { return this.cancelButton; }

    }

    I don’t like the idea of "assumed" private members. That to me seems to fix a manifestation of the problem rather that just fix the problem itself. I’d rather see things like object binding just work with public fields as well as properties.

    I look forward to VS 2005 and being able to use expansion to create my properties.

  12. I think that despite of this rutine work – using properties is still the right way. Modern app look like this:

    database tables/fields mapped to classes/properties mapped to UI fields. And of course we use stored procedures when speaking to database tables. It is so easy to map SP parameters to class properties (datatypes, etc) that it makes it be the right way.

  13. Josh says:

    Download the free add-in called QickCode from http://www.dvxp.com/en/QuickCode.aspx. It lets you customize simple keyword expansion from within VS.net 2002/2003. It’s really cool, and if you consider that you can reduce the amount of typing you do, yet end up with the encapsulation of properties, it’s well worth the $29…

  14. 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 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 “property tax” the whole time. This may be heretical, since “use properties” has been the common guideline. What do you think? [C# Stuff]…

  15. Daniel O'Connell says:

    Ryan:

    Do you write addremove handlers for all of your events or are you ok with those assumed private members?

    The problem isn’t nessecerily that binding doesn’t work with fields as that fields aren’t properties and don’t provide *any* of the extras that properties do. I think that if the language had been designed assuming public fields would never be used, property design would have been considerably simpler. This kind of work already went into events because writing simple event handlers manually is a pain and usually a waste of effort. Writing simple property accessors manually is a pain as well, but it wasn’t handled anywhere near as gracefully.

  16. Thomas Eyde says:

    It’s too late now, but what about

    public field string _name;

    public property string Name;

  17. I generally would agree with Ryan about assumed private members being a bad thing. But I also like what I think Thomas is hinting at – what if a simple

    public property string Name;

    was equivalent to something like

    private string ___name;

    public string Name

    {

    get { return ___name; }

    set { ___name = value; }

    }

    BUT if you declared Name using get & set, nothing would be automagically linked up?

    Of course is there really any difference between that and a public field?

  18. Daniel O'Connell says:

    > Of course is there really any difference between that and a public field?

    As a matter of implementation, there is quite a bit of difference. A property != a field and should never be considered to, even if they look alike in source. They may provide the same service but they do it quite differntly. Its been suggested that a property is far closer to a method than a field. I don’t quite understand why people are so unaware of the differing semantics. These "good as" arguments are a touch scary.

  19. adam says:

    2 points for me on using properties over public fields (for simple get/set, no other logic implementations) are consistency and debug-ability.

    From the debugging side it means that a break point can be placed on a single point and all writes to a variable can be trapped.

    > Of course is there really any difference between that [get/set property] and a public field?

    Properties can’t be passed as ref/out method parameters.

  20. Kris Williams says:

    Why not just make all read-only accessors/properties not read-only to the local object, or use a built-in property-property ".Value"? to represent the underlying private member. Maybe a friend modifier to allow objects from the same namespace to access the private member?

    // read-only

    property string Name {get;}

    // write-only: initializer built in…

    property friend Location Location {set;} = new Location("Unknown");

    // read-write

    property int Age = 0;

    // somewhere else in the same object scope

    // use .Value to short-circuit accessibility

    this.Name.Value = "Your Name";

    this.Age = 33;

    this.WhereAbouts = new Location("Home");

    // in another object in the same namespace:

    Location personLocation = Person.WhereAbouts.Value;