Sunday, September 6, 2009

Good programming practices

While conventions and standards introduce uniformity to code and make it easily understandable, developers are strictly advised to follow some good coding practices listed over a period of time. If you browse the Internet, you will find a vast number of resources available on good programming practices. Some of them have stood with time and are always relevant, some are not really significant and some do not go along with our conventions. However, there are a few points that are relevant to our organization and to the general C# developers; and applicable to the code we write regularly.

Today, we will have a look at such “good programming practices”:

Variables

  • Declare one variable per line. Do not list multiple variables in the same line although they are the same type. By declaring one variable per line, you can easily add comment for each variable, which you should (must for member variables).
  • Declare and initialize variables in the same order they are used. This applies to both member and local variables.
  • Always initialize variables, if possible at the point of declaration. There should a valid reason if a variable is not initialized.
  • Declare and initialize variables close to where they are used. This is very important because only by identifying their scope of usage, one can decide which variables should stay local and which variables are required as member variables. The idea is to declare and use variables as locally as possible. By declaring variable close to their usage, however, does not mean that variables should be declared anywhere. In methods, the variable declarations should be on the top.
  • Do not make member variables public or protected. Keep them private and expose them through public/protected properties.
  • In a method, use “this.” for member variables. This way, member variables can be easily distinguished from local ones.

Constants
  • Constants should be used instead of hardcoded numbers in code. Declare and initialize constants at the top and use them throughout the code.
  • Remember, the rule for variables about one declaration per line applies to constants as well.

Session variables
  • Use session (or even application) variables sparingly. Session variables should be used only when some data has to be stored throughout the session of the user. Never use them for temporary storage purposes.
  • Do not store large objects in session variables. 
  • Do not use session variables throughout the code. Use session variables only within the classes and expose methods to access the value stored in the session variables.

Control flow (branches and loops)
  • All flow control primitives (if, else, while, do, for, switch) should be followed by a block (a pair of curly braces) even if it is empty. Remember to put a curly brace on a new line always.
  • All switch statements should have a default label as the last case label. 
  • Convert strings to lowercase or uppercase before comparing. It is important to bring string on both sides of a condition to one case before performing comparisons.
  • Do not make explicit comparisons to boolean values: true or false. 
  • Use ternary operator for simple if-else statements. 
  • Use String.Empty instead of “” while checking if a string is empty.
  • Do not compare floating points using == or != operators. 
  • Use StringBuilder class instead of String when you have to manipulate string objects in a loop.
  • When casting types, always check if there is a possibility of loss of precision.

Methods
  • Name a method so that it tells what it does. It saves you from writing lot of comments. For example, instead of naming a method that saves a phone number as SaveData (string phoneNumber), use SavePhoneNumber (string phoneNumber).
  • Do not create two methods with names that differ only by case (although their purpose or scope is different). This applies to all objects including namespaces, classed, variables etc.
  • A method should not have only one return statement. Avoid multiple or conditional return statements.
  • Never return null for an empty collection.
  • All variants of an overloaded method should be used for the same purpose and have the same behavior.

Events and delegates
  • Always raise events through a protected virtual method.
  • Always use the sender/arguments signature for event handlers.
  • Do not programmatically call an event handler. Instead, code the action in a separate method and call the method.

Some general tips
  • Avoid fully qualified type names. Use the using statement instead.
  • Do not hardcode strings. Use resource files.
  • Always use external style sheet to control the look and feel of the pages (even for images).
  • Keep name of querystring arguments short (2-3 characters). For e.g., use “fn=test.txt&v=1.1” instead of “filename=test.txt&fileversion=1.1”.
  • If you have opened database connections, sockets, file stream etc, always close them in the finally block.
  • Always set a reference field to null after usage to tell the Garbage Collector that the object is no longer needed. 
  • Avoid implementing a destructor. If a destructor is needed, also use GC.SupressFinalize.

0 comments: