Here’s my message from the 30th DevExpress newsletter. I can’t remember where or when I first learned this trick, but it was fairly early on in my career.
Improve your code ... by reading
If you asked a random selection of developers how to improve their code -- its clarity, expressiveness testability, robustness, etc -- you'd probably get a whole lot of good advice about practicing, TDD, BDD, pair programming, and so on, so forth.
In other words, to improve your code, write more of it. Kind of goes along with the idea of improving your piano playing by playing the piano more.
But there's another way to improve your code, and that is reading other people's code.
Let me explain. By reading other people's code, you gain insight into their style (and your own), you gain understanding of particular programming techniques, you gain appreciation of larger code bases, you may even learn something new.
Of course, I'm not suggesting that you sit back, a cold glass of something brewed in hand, half surfing some code in a window all the time keeping an eye on your twitter feed. No, in order to read code, you have to be able to glean enough knowledge about it that you can criticize it, formulate what you like about it and what you don't, or put into words why you would have done something differently.
First of all, find some code. I would start off with something fairly small and work your way up. There are many projects at CodePlex or CodeProject that you can take a look at. Find a implementation that interests you or that is written by someone you've heard of.
Download it and take a high level view. What's the structure of the solution? Does there appear to be one class per file? Pay attention to the names and identifiers: do they imply an implementation? Or are they somewhat opaque? Does it even compile? (Providing you have the required infrastructure, of course.)
Then proceed from either a top-down or bottom-up approach. I tend to go for the latter: once I have some understanding of how well the low-level classes are designed and written, I can take that knowledge up with me into the higher-level modules. Some people I know take the opposite approach: gain an understanding of the very top-most layers, what the application or class model is supposed to do, and then burrow down wherever your fancy takes you.
While you are doing this, pay attention to the supporting infrastructure: the test modules (if any), the external libraries it uses, the comments, even the local structure of the code (for example, does the author use exclusively for, foreach, some functional equivalent, LINQ, etc, or does it vary according to purpose).
Make notes as you go along, not necessarily in a separate file, but as comments in the code itself. If you think that you could have written something better, do so, and check that your version works as well as the original. Make use of a refactoring tool in this endeavor.
Once you've exhausted one project, go find another and do the same thing. And then do it again, and again. Gradually grow the size of the project you read and analyze until you feel you're at the point that you can help that project get better, and then write the project lead with some suggestions. Become involved.
I guarantee that if you read other people's code regularly, you'll find your own code improving.
The only thing I’d add is that all you see when reading other people’s code is the end product. You do not see all the dead ends the author hit on the way, you don’t see the mistakes, or the code that failed the tests. You just see the (presumably) polished code, the best implementation the author was able to write. Of course, providing that the author is hosting on some SVN or Git repository (and the author was vigilant about updating said repository), you could take a look through the version diffs to see how the code evolved. I dare say though that this is no longer using the code as a static pedagogical device but as a dynamic investigation into how code is written. You’d still get information, but it would be different information.