At work weíre currently discussing coding standards, specifically to synchronise development in two countries and keep the style consistent across the teams. You know, the usual stuff.
When people start discussing coding standards, it quickly devolves into a religious debate and honestly, I think a lot of it comes down to personal preference. Because of that, Iím going to spend a post or two telling your why youíre wrong and why I wouldnít take your code to dinner however much it offered to put out. Because clearly my way is the only right way!
Joking aside, I want to go into some detail on how I present and write my code, and hopefully explain why. Itís all going to be slanted towards (who do I think Iím kidding, itís going to be in) C# so as ever, your mileage may vary with any advice you extrapolate. Iím going to start out by showing you some bad examples, attempt to explain why I think theyíre bad, and offer my alternative.
Properties and Variables
The way you declare your properties and variables is seemingly insignificant, but if you get it wrong it trashes the readability of your code. Take this code sample for example:
All Iíve done in the above screenshot is declare a few properties, a few instance variables and a constructor. And it looks awful and un-maintainable despite the lack of any significant code smell, all due to the manner in which Iíve declared the variables. Itís a laundry list of mistakes.
- Using field backed properties when an auto-property will suffice.
- Defining auto-properties split across multiple lines for no explicable reason.
- Adding utterly redundant code comments (the code-criticism comments aside).
- Terrible and ambiguous variable naming.
- Variable names that contain hints at data types.
The above code sample is practically unreadable, even without the comments, itís long winded and obtuse:
Now, I come from the school of thinking that is pretty much convinced that typing things is bad, repeating yourself is bad, hell, writing code is bad. So donít. Less really is more, pick your favourite buzz phrase. Cleaning up your code should involve making it as simple and as clear as is humanly possible.
Thankfully, if you take advantage of the language features of C#3, you can quickly make something like that look like this:
Just by tidying up the way you declare and use your variables, you can make your code eminently more readable. If you compare the two examples, youíll see that all Iíve done is
Use single line declarations for auto-properties.
- Why waste 3-5 lines on an auto-property that can easily fit one one without any loss in readability.
Removed data backed properties in exchange for auto-properties with access modifiers on the setter.
- Functionally equivalent and far neater
Renamed badly named properties (in the first example ďFLineOfAddressĒ) to be more meaningful.
- Remove abbreviations where possible, they damage readability
- Assume the maintainer of your code has no business knowledge, make things easy
- Meaning is always better in variable names than in comments / meta-data
- Donít fear long variable names, modern IDEs have auto-complete, you donít have to type that stuff by hand. Embrace your tooling!
- If you canít tell whatís in your property or variable from itís name, youíve failed, go back and try again.
- This honestly includes stuff like foreach(var item in MyCollection) and StringBuilder sb = new StringBuilder(); Both bad and wrong, donít do it.
Only retained comments where the comment data is truly meaningful.
- The above example isnít particularly good (everyone knows what a URL is), but only keep comments in your code where they add something that you couldnít attain with careful renaming and code restructuring / refactoring. The meaning of your code should be obvious to the reader without metadata.
Stick to a solid naming convention for public / private / protected variables and properties.
- The well trodden convention Iím following above is lowerCamelCase plusÖ
- A leading underscore for private instance variables (determining scope)
- Regular lowerCamelCase for local variables
- UpperCamelCase for property names, constants and statics.
- No data types in your variable names. This is not 1980. The IDE gives you all that lovely meta-data, donít give yourself RSI duplicating it in your variable names.
Cleaning up usage
- Removing this., you get the same scoping from using _ by convention in your variable names, save those fingers from RSIÖ
- Using instance and local variables instantly becomes clearer by sticking to convention.
Using var to reduce duplication in code.
This is often controversial but I feel that using var, for the most part, reduces the amount of typing required without any loss of clarity. Take the following examples:
Itís clear to me that no clarity is lost by not typing "StringBuilderĒ twice. Itís still right there in front of you and allows you to keep your variable declarations more uniform. Despite popular misconception this doesnít affect the type safety of C#, the language and your variable are still strongly typed, the compiler just infers that when you said var you meant StringBuilder at compile time. If it isnít really obvious what an object is when you instantiate it, youíre probably doing something really wrong elsewhere.
People occasionally like to argue that while for declarations var is all well and good, when youíre using it for return values it causes a loss of clarity. Itís an interesting point but always feels slightly off the mark to me. Whenever people attempt to give me an example of this lack of clarity, itís always that th
eir variables or properties are ambiguously or inappropriately named, and the code clarity can be regained and even improved by naming the variables involved in a more descriptive way. Take the following snippet for example:
In the first case, Iíd agree that using a var called ďlĒ to store the return value of that method would lead to a loss in clarity. But if you had string l = RetrieveTextLabel(); and then, say, 20 lines down attempted to use a variable called ďlĒ youíd probably deserve a swift kicking for naming something so poorly. By contrast, var textLabel is exceptionally descriptive. People also occasionally say that using var in foreach loops causes this ambiguity, but again, if you name your collection appropriately and your yeilded value correctly, it really is never an issue.
Even more importantly, if you get your naming right, var actually helps you quickly refactor your code. As long as you understand the ďmeaningĒ of your variables, the IDE can fill in the blanks with regard to data types, because for the most part, it really doesnít matter what type of data is actually in that variable when youíre reading the code as long as itís meaning is a known quantity. I actually feel that the dynamic language crowd learnt this lesson long ago, and people that work predominantly in strongly typed languages actually tend to rely on the type system like a crutch to excuse terrible naming conventions. Time to learn from PHPÖ
To make your code readable you should stick to conventions for naming, always strive to add meaning in variable names and be as brief as possible. Donít litter your code with crap and youíll be thankful for it later.
Obviously, this is all my opinion, but I swear by it.
Iíll be following up this post in the next few days with some continued patterns for readable code.