<CharlieDigital/> Programming, Politics, and uhh…pineapples

25Jul/09Off

Automatic Properties (And Why You Should Avoid Them)

Posted by Charles Chen

Ah yes, automatic properties.  Insn't it great that you don't have to do all of that extra typing now?  (Well, you wouldn't be doing it anyways with ReSharper, but that's besides the point.) For some reason, they've never sat well with me; they just seem like a pretty useless feature and, not only that, I think it severely impacts readability. 

Quick, are these members in a class, an abstract class, or an interface?

int Id { get; set; }

string FirstName { get; set; }

string LastName { get; set; }

Can't tell!  Perhaps you code at a leisurely pace, but when I'm in the zone, I'm flying around my desktop, flipping through tabs like crazy, ALT-TABbing between windows, and typing like a madman.  It's happened to me more than once where I've been working in a file, trying to add some logic to a getter and getting weird errors only to realize that I was working in the interface or abstract class instead of the concrete class.  Of course I don't normally write many non-public properties, but it's easy to make the mistake of missing the access modifier if you're working furiously and tabbing back and forth, especially if the file is long (so that you can see the class/interface declaration at the top of your file).

Look again:

public interface IEmployee
{
	int Id { get; set; }

	string FirstName { get; set; }

	string LastName { get; set; }
}

public class Employee
{
	int Id { get; set; }

	string FirstName { get; set; }

	string LastName { get; set; }
}

public abstract class AbstractEmployee
{
	int Id { get; set; }

	string FirstName { get; set; }

	string LastName { get; set; }
}

It's even more confusing when you're working within an abstract class and there's implementation mixed in.  Not only that, it looks like a complete mess as soon as you have to add custom logic to the getter or setter of a property (and add a backing field); it just looks so...untidy (but that's just me; I like to keep things looking consistent).  I'm also going to stretch a bit and postulate that it may also encourage breaking sound design in scenarios where junior devs don't know any better since they won't think to use a private field when the situation calls for one (just out of laziness).

I get that it's a bit more work (yeah, maybe my opinion would be different if I had to type them out all the time, too - but I don't :P), but seriously, if you're worried about productivity, then I really have to ask why you haven't installed ReSharper yet (I've been using it since 2.0 and can't imagine developing without it).  It's easy to mistake one for the other if you're just flipping through tabs really fast.  I've sworn off using them and I've been sticking to my guns on this.

There are three general arguments that I hear, from time to time, from the opposition:

  1. Too many keystrokes, man!  With R#, you simply define all of your private fields and then ALT+INS and in less than 5 or 6 keystrokes, you've generated all of your properties.  I would say even less keystrokes than using automatic properties since it's way easier to just write the private field and generate it using R#.  If you're worried about productivity and keystrokes and you're not using R#, then what the heck are you waiting for? 
  2. Too much clutter, takes up too much space! If that's the case, just surround it in a region and don't look at it.  I mean, if you really think about it, using KNF instead of Allman style bracing throughout your codebase would probably reduce whitespace clutter and raw LOC and yet...
  3. They make the assembly heavier!  Blah!  Not true!  Automatic properties are a compiler trick.  They're still there, just uglier and less readable (in the event that you have to extract code from an assembly (and I have - accidentally deleted some source, but still had the assembly in GAC!)).  In this case, the compiler generates the following fields:
    <FirstName>k__BackingField
    <Id>k__BackingField
    <LastName>k__BackingField

Depending on the project, there may also be unforseen design scenarios where you may want to get/set a private field by reflection to bypass logic implemented in a property (I dunno, maybe in a serialization scenario?).

So my take?  Just don't use them, dude!


Update: To clarify, McConnell has a whole section of Code Complete which discusses "code shape" and how it affects readability (see chapter 31). I think this is along the same veins. You gain NOTHING by using automatic properties, but you sacrifice readability and clarity. I don't think that the argument of "saving a couple lines" is a valid one since you can just as easily collapse those into regions and save many more lines or even switch bracing styles.

As McConnell writes:

"Making the code look pretty is worth something, but it's worth less than showing the code's structure. If one technique show the structure better and another looks better, use the one that shows the structure better."

"The smaller part of the job of programming is writing a program so that the computer can read it; the larger part is writing it so that other humans can read it."

My belief is that using backing fields shows the structure of the class file better than using automatic properties (which was my point in the blog post). Automatic properties are a convenience for the author, but it sacrifices structural cues to the purpose and usage of a given code file, IMO.  There is no benefit except to save a few keystrokes for the author, but in that case, even more keystrokes can be saved using R# and explicit backing fields.

Filed under: .Net, Rants 4 Comments