次の方法で共有


Properties vs public fields redux...

My blog reader burped recently, and gave forth a post (and reply) than Rico wrote last September, but since I didn't comment on it then, I'll comment on it now. And, yes, I've written about this in the past...

Basically, this revolves around the question of using properties, or using public fields. And I have a slightly different point to make than Rico is making, his point being that sometimes you need to break these guidelines for performance reasons (which I agree with, but which is not my point).

But first, a bit of history...

Back in the early days of .NET, we (and by "we", I mean "other people") were coming up with the .NET framework library coding guidelines and the CLS as a way of making sure that developers could use assemblies developed in multiple languages without severe cranial performance issues. Meetings were held, discussions ranged far and wide, and the CLS and coding guidelines came into being.

And they were pretty good, though they only covered the public appearance of classes. You could use hungarian in the internals of a class, if you wanted to.

We also discussed whether we would come out with a set of guidelines that talked about how things should be done inside your class. For C#, we decided not to do this, and if any of you have ever spent time talking about where braces belong or whether source code should use spaces or tabs, you understand why we decided not to do this.

But I'm afraid that it unfortunately gave the impression that the library coding guidelines should be the drivers for all code that you write, and I think that's the wrong way to look at things. Others may differ inside MS, but they can write their own blog posts...

On the specific subject of properties, the question can be boiled down to:

If I have a field with no special behavior, should I write a "just in case" property (with trivial get/set), or should I expose a public field?

The reason that the library design guidelines suggest you write a property here is that it is important that libraries be easily versioned. If you put a property in there ahead of time, you can change the property implementation without requiring users to recompile their code.

That, in my book, is generally a "good thing".

Or, to put it another way, I rank the ability to version easily higher than the cost of the extra clutter in the class and increased size of the assembly that comes from the property.

But, if the clients of a class are always compiled together with a class - or at least shipped together - then there is no versioning issue to consider. In that case, I think it's a bad idea to write the "trivial property" - all you've done is complicate your code without any benefit. If the public field you write needs to be a property, then just make the change and recompile.

I've switched over to writing this code, and I have to say that when I have to work with old code with trivial properties, it bothers me.

(Oh, and I also made the same choice as Rico when I had to do some graphical stuff...)

Comments?

Comments

  • Anonymous
    February 01, 2007
    In principle, I agree.  If I haven't worked with dozens of clients working with code from hundreds of programmers where a public field invariably ends up being used externally (because it can).  This, of course, leads to great discomfort when the class is refactored and that field changes type. There's so many things to take into account when simply creating a class--most of which are ignored to simply "get it out".  in .NET alone: internal or not, public or protected, sealed or not (which affects whether protected should be used), etc.  ...often leading to simply accepting the defaults... While I agree to your comments in principle, you're not suggesting design of classes "intended" to be used only internally or within the same assembly (regardless of what you tell the compiler--by possibly not including "internal") should be given the same amount of thought as an intentionally public-facing class.  ...Which I'm afraid this is what some will take away, or will use in their "properties are bad" arguments (yes, there are still some out there).

  • Anonymous
    February 01, 2007
    I'd love to see the ability to declare a trivial property and have the compiler generate the backing field and getters and setters. For example: public property string Name; That way I get the conciseness of fields, but can substitute in a more complex implementation if needed without breaking compatibility with existing clients. This is a lot like the event keyword. Syntactic sugar, but tasty nonetheless. :)

  • Anonymous
    February 01, 2007
    Kevin, Back after 1.0 shipped, we spent a fair amount of design team time trying to come up with something like that. We tried a bunch of different syntactical options, but didn't come up with one that worked well, and IIRC we decided that there were other more important things to discuss. I don't know what the team thinks about that now - at that point we were trying to tread lightly in terms of adding things, and Linq negates that approach a bit... Peter, I do think that classes with different clients have different design goals. And I do think that external classes require more work, simply because it's so much more painful to refactor them later if you don't get it right up front. I hadn't thought of internal classes becoming accidentally external. I'm not sure it changes my opinion, but it does provide some food for thought. Eric.

  • Anonymous
    February 01, 2007
    Hmm. What's wrong with public property string Name; :P

  • Anonymous
    February 01, 2007
    In principal I agree with you. But exposing member field bothers me, now suddenly you have to change your naming convention for that member field, i.e. “memberField” has to change as “MemberField”, I believe it change readers perception about code when she see the code :) Dhananjay

  • Anonymous
    February 01, 2007
    I agree with this one too - and I have went back and forth and I'm sure I will continue to do so. One question is, should those public fields be capitalized? It used to make refactoring easier if you later add a property. Then again with tools now it is pretty easy either way. Still it is something I debate with myself every time (usually I use lowercase). Also, I'm not sure why they couldn't have used "public property string Name;" -- essentially the same thing is done with events. Also it could be a nice flag to the final jit code generator that the method call can be dropped for direct variable access in most cases (where now they probably have to find a usage pattern).

  • Anonymous
    February 01, 2007
    One place I see using public fields do not hurt but instead helps a lot, are the DTO (Data Transfer Objects). Making DTO use public fields no only saves you about 75% of the code, but also ensures that there will be no logic in there - which is a good thing for a DTO :-)

  • Anonymous
    February 01, 2007
    a property which could automagically generate FooChanaged events at the same time would be nice :)

  • Anonymous
    February 01, 2007
    Kevin/Robin: The syntax you're suggesting for automatically generating the backing code for trivial properties is exactly what C++/CLI does, and it's one of the few areas where C++/CLI has better usability than C#. A mild annoyance is that the name of the generated field is not known, so you can't access the field directly even from within the host class, but I can't think of any reason why this would be an issue; it just doesn't chime with my preconception of where the boundaries "ought" to lie.

  • Anonymous
    February 02, 2007
    Changing a public field in a property is not only binary incompatible but also at the source-code level! A field can be passed as an out- or ref- parameter while a property cannot. So even if you ship the clients of your class together with your class, just recompiling your code may not solve the problem. Therefore: always use properties! I've written something about this here: http://kristofverbiest.blogspot.com/2007_02_01_kristofverbiest_archive.html

  • Anonymous
    February 02, 2007
    The comment has been removed

  • Anonymous
    February 02, 2007
    The comment has been removed

  • Anonymous
    February 02, 2007
    Some nice comments on what I wrote . First, a non-controversial question. Robin asked whether you would

  • Anonymous
    February 02, 2007
    Well, if there would be always generated/ automatic properties - that would be a very large overhead. :) Or maybe change syntax as such, that each native field should have a keyword "field" and without one it would be automatic property? But as the things are evolving with c#3 i do not see that happening.

  • Anonymous
    February 02, 2007
    The way the language works is fine I'd say - having public field and the property mechanism gives you the most flexibility and the JIT will give you inlining for performance so you don't pay for trivial property implementations. This ensures we can do the right thing. But what would be cool if Visual Studio could help with Intellisense and the debugger display. An option to filter the property/field view would be handy. Public private (for this pointers). For example, most times I wish we could hide fields from the intellisense view. Or only show properties, only methods or only public etc.

  • Anonymous
    February 03, 2007
    C# 3.0 is getting the automatic properties that Kevin proposes. The syntax is as follows: public string Name { get; set; } Look here: http://aspiring-technology.com/blogs /troym/archive/2006/11/19/53.aspx

  • Anonymous
    February 04, 2007
    I am not too fond of the proposed syntax for the trivial property; it looks too much like an abstract property. And why the { get; set}? If we leave out one of them, we have a useless property; one we can read, but not update. Or write to, but not read. No. I prefer public property string Name;

  • Anonymous
    February 04, 2007
    Thomas, I think the { get, set } is actually useful. Look at this: public string Name { get; protected set; } or public string Name { virtual get; private set; } Of course 'string Name { get; } would we pretty useless :-)

  • Anonymous
    February 05, 2007
    I'm with Thomas on the syntax - both for simplicity and for the nice symmetry with events.

  • Anonymous
    February 08, 2007
    Eric Gunnerson just posted Properties vs public fields redux... It's no secret that I agree with Eric

  • Anonymous
    February 09, 2007
    seems like public fields should also be marked internal then?

  • Anonymous
    February 16, 2007
    You've been kicked (a good thing) - Trackback from DotNetKicks.com

  • Anonymous
    February 20, 2007
    Of course, I'd prefer not to use trivial properties but I found one reason : reflection. In most of the framework databound controls, reflection is used to find the property matching the datamember. For that reason, I came back to trivial properties in my domain classes...

  • Anonymous
    February 27, 2007
    I just spent a couple of hours on many different blogs/forums trying to find out when to use fields and when to use properties. And, of course, without getting The Answer. But, Fabien's point here is right on the spot! That's exactly why I started to read about this topic(again...), and that's a very important reason to use properties and not fields. Thanks Fabien, now I am able to bind my dataclass to a gridview with two lines of code :)

  • Anonymous
    May 19, 2007
    Why so many people like property much than public field even though inside the property there is no other

  • Anonymous
    August 18, 2007
    Properties vs public fields redux...

  • Anonymous
    August 21, 2007
    Di una cosa simile, ne discutevo tempo fa con un paio di amici. L'argomento citato in questo post