1.15. Elements of C# Style

One of the trademarks of good programmers is that they produce readable code. Your professional life will probably not involve generating code by yourself on a mountaintop, so your colleagues will need to be able to work with and modify your programs. Here are some guidelines and conventions that will help you to produce clear, readable C# programs.

1.15.1. Proper Use of Indentation

One of the best ways to make C# programs readable is through proper use of indentation to clearly delineate statement hierarchies. Statements within a block of code should be indented relative to the starting/end line of the enclosing block (that is, indented relative to the lines carrying the braces). The examples in the MSDN web pages use four spaces, but some programmers use two spaces and others prefer three. The examples in this book use a two-space indentation convention.

If you are using Visual Studio, you can configure the indentation spacing as one of the VS options.


To see how indentation can make a program readable, consider the following two programs. In the first program, no indentation is used:

using System;

public class StyleDemo
{
static void Main() {
string name = "cheryl";
for (int i = 0; i < 4; i++) {
if (i != 2) {
Console.WriteLine(name + " " + i);
}
}
Console.WriteLine("what's next");
}
}

It is easy to see how someone would have to go through this program very carefully to figure out what it is trying to accomplish; it's not very readable code.

Now let's look at the same program when proper indentation is applied. Each statement within a block is indented two spaces relative to its enclosing block. It's much easier now to see what the code is doing. It is clear, for example, that the if statement is inside of the for statement's code block. If the if statement condition is true, the WriteLine method is called. It is also obvious that the last WriteLine method call is outside of the for loop. Both versions of this program produce the same result when executed, but the second version is much more readable.

using System;

public class StyleDemo
{
  static void Main() {
    string name = "Cheryl";
    for (int i = 0; i < 4; i++) {
      if (i != 2) {
        Console.WriteLine(name + " " + i);
      }
    }
    Console.WriteLine("What's next");
  }
}

This code's output is shown here:

Cheryl 0
Cheryl 1
Cheryl 3
What's next

Failure to properly indent makes programs unreadable and hence harder to debug—if a compilation error arises because of imbalanced braces, for example, the error message often occurs much later in the program than where the problem exists. For example, the following program is missing an opening brace on line 11, but the compiler doesn't report an error until line 25!

using System;
public class Indent2
{
  static void Main() {
    int x = 2;
    int y = 3;
    int z = 1;

    if (x >= 0) {
      if (y > x) {
        if (y > 2) // missing opening brace here on line 11, but...
          Console.WriteLine("A");
          z = x + y;
        }
        else {
          Console.WriteLine("B");
          z = x - y;
        }
      }
      else {
        Console.WriteLine("C");

z = y - x;
      }
    }
    else Console.WriteLine("D");  // compiler first complains here!(line 25)
  }
}

The error message that the compiler generates in such a situation is rather cryptic; it points to line 25 as the problem and doesn't really help us much in locating the real problem on line 11:

IndentDemo.cs (25,5) error:
Invalid token 'else' in class, struct, or interface member declaration.

However, at least we've properly indented, so it will likely be easier to hunt down the missing brace than it would be if our indentation were sloppy.

Sometimes we have so many levels of nested indentation, or individual statements are so long, that lines "wrap" when viewed in an editor or printed as hardcopy:

while (a < b) {
    while (c > d) {
      for (int j = 0; j < 29; j++) {
        x = y + z + a + b – 125*
(c * (d / e) + f) - g + h + j - l - m - n + o +
p * q / r + s;
      }
    }
}

To avoid this, it is best to break the line in question along white space or punctuation boundaries:

while (a < b) {
  while (c > d) {
    for (int j = 0; j < 29; j++) {
      // This is cosmetically preferred.
      x = y + z + a + b – 125*(c * (d / e) + f) - g +
          h + j - l - m - n + o + p * q / r + s;
    }
  }
}

1.15.2. Use Comments Wisely

Another important feature that makes code more readable is the liberal use of meaningful comments. Always keep in mind when writing code that you know what you are trying to do, but someone else trying to read your code may not. (We sometimes even need to remind ourselves of why we did what we did if we haven't looked at code that we've written in awhile!)

If there can be any doubt as to what a section of code does, add a comment:

  • Include enough detail in the comment to clearly explain what you mean.

  • Make sure that the comment adds value; don't state the obvious. The following is a fairly useless comment because it states the obvious:

    // Declare x as an integer, and assign it an initial value of 3.
    int x = 3;

  • Indent each comment to the same level as the block of code or statement to which it applies.

For an example of how comments are important in making code readable, let's revisit an example from earlier in the chapter:

using System;

public class IfDemo
{
  static void Main() {
    double sales = 40000.0;
    int lengthOfService = 12;
    double bonus;

    if (sales > 30000.0 && lengthOfService >= 10) {
      bonus = 2000.0;
    }
    else {
      if (sales > 20000.0) {
        bonus = 1000.0;
      }
      else {
        bonus = 0.0;
      }
    }

    Console.WriteLine("Bonus = " + bonus);
  }
}

Because of the lack of comments, someone trying to read the code might have difficulty figuring out what business logic this program is trying to apply. Now let's look at the same program when clear, descriptive comments have been included in the code listing:

using System;

// This program computes the size of an employee's bonus.
//
// Written on March 5, 2008 by Jacquie Barker and Grant Palmer.

public class IfDemo
{
  static void Main() {
    // Quarterly sales in dollars.
    double sales = 40000.0;

    // Length of employment in months.
    int lengthOfService = 12;

    // Amount of bonus to be awarded in dollars.
    double bonus;

    // An employee gets a $2K bonus if (a) they've sold more than $30K this
    //quarter and (b) they've worked for the company for 10 months or more.
    if (sales > 30000.0 && lengthOfService >= 10) {
      bonus = 2000.0;
    }
    else {
      // Otherwise, ANY employee who has sold more than $20K this quarter
      // earns a bonus of $1K, regardless of how long they've worked for
      // the company.
      if (sales > 20000.0) {
        bonus = 1000.0;
      }
      // Employees who have sold less than $20K earn no bonus.
      else {
        bonus = 0.0;
      }
    }

    Console.WriteLine("Bonus = " + bonus);
  }
}

The program is now much more understandable because the comments explain what each section of the code is intended to accomplish.

1.15.3. Placement of Braces

For block structured languages that use braces, {...}, to delineate the start/end of blocks (for example, C, C++, Java, C#), there are two general schools of thought as to where the left/opening brace of a code block should be placed.

The first style is to place the left brace at the end of the line of code that starts the block and the matching right/closing brace on a line by itself:

public class Test { //  Left brace on same line as class declaration

    static void Main() {  //  Ditto for method headers

for (int i = 0; i < 3; i++) { //  And again for control flow blocks
       Console.WriteLine(i);

     //  Each closing brace goes on its own line:
     }
    }
   }

An alternative opening brace placement style is to place every opening brace on a line by itself:

public class Test
{
    static void Main()
    {
        for (int i = 0; i < 3; i++)
       {
         Console.WriteLine("i");
       }
     }
   }

Another possibility is a hybrid of these two approaches: the second style (brace on a separate line) is used for class declarations, and the first style (brace on the same line) is used for virtually everything else:

//  Left brace for class declaration on its own line:
public class Test
{
  //  but all others are on the same line as the initial line of code.
  static void Main() {

       for (int i = 0; i < 3; i++) {
         Console.WriteLine(i);

       //  Each closing brace goes on its own line:
       }
     }
   }

There is no absolute right or wrong style because the compiler doesn't care one way or the other. It is a good practice to maintain consistency in your code, however, so pick a brace placement style and stick with it.

Either way, it is important that the closing brace for a given block be indented the same number of spaces as the first line of code in the block so that they visually line up, as was discussed earlier.

1.15.4. Self-Documenting Variable Names

As with indentation and comments, the goal when choosing variable names is to make a program as readable, and hence self-documenting, as possible. Avoid using single letters as variable names, except for loop control variables. Abbreviations should be used sparingly, and only when the abbreviation is commonly used and widely understood by developers. Consider the following variable declaration:

int grd;

It's not completely clear what the variable name grd is supposed to represent. Is the variable supposed to represent a grid, a grade, or a gourd? A better practice is to spell the entire word out:

int grade;

At the other end of the spectrum, names that are too long, such as the following example, can make a code listing overwhelming to anyone trying to read it:

double averageThirdQuarterReturnOnInvestment;

It can sometimes be challenging to reduce the size of a variable name and still keep it descriptive, but do try to keep the length of your variable names within reason.

NOTE

We'll talk about naming conventions for other OO building blocks, such as methods and classes, as we introduce these topics later in the book.

The .NET Framework provides a series of naming guidelines to promote a uniform style across C# programs. If you want to read the complete details on the C# naming conventions, the guidelines can be found at the following site: http://msdn.microsoft.com/en-us/library/ms229045.aspx.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset