Introduction
The main reason for using a consistent set of coding conventions is to standardize the structure and coding style of a script or set of scripts so that you and others can easily read and understand the code. Using good coding conventions results in clear, precise, and readable source code that is consistent with other language conventions and is intuitive. Coding conventions can include the following:
- Naming conventions for objects, variables, and procedures
- Commenting conventions
- Text formatting and indenting guidelines
Everyone should learn and practice the coding standards for higher performance, compromising reliability and maintainability. If our code is not reliable and maintainable, we will be spending lot of time to identify issues, trying to understand code etc throughout the life of our application.
Objectives
The objectives of this standard are:
- To document the C# coding conventions.
- To improve the quality of the deliverable software and its associated documentation.
- To improve communication within the development and maintenance teams.
- To decrease the costs associated with the software and its associated documentation.
Purpose of coding standards and best practices
Design and coding conventions are important for a number of reasons:
- Software is read many more times than it is written, often by someone other than its developer.
- Coding conventions increase the readability of the software, permitting software engineers to understand and maintain software more quickly and correctly.
- Maintenance cost is more rather than development.
- The developer will rarely involve in maintenance.
- Providing standard coding conventions permits the developer to concentrate on more important issues such as design.
Naming Conventions and Standards
Variable Naming Conventions
Subtype | Prefix | Example |
Boolean | bln | blnFound |
Byte | byt | bytRasterData |
Date (Time) | dtm | dtmStart |
Double | dbl | dblTolerance |
Error | err | errOrderNum |
Integer | int | intQuantity |
Long | lng | lngDistance |
Object | obj | objCurrent |
Single | sng | sngAverage |
String | str | strFirstName |
To enhance readability and consistency, you might encounter the following prefixes with descriptive names for variables in your C# code.
Object Naming Conventions
Use appropriate prefix for the UI elements so that you can identify them from the rest of the variables. All the added objects in Name mapping file have the property called “ObjectType”. If the object needs to be differentiate from the other object few below mention property will be added.
(ObjectIdentifier, idStr, innerText, title, ID)
For Example:-
Control | Prefix |
Label | lbl |
Text | txt |
DataGrid | dtg |
Button | btn |
Hyperlink | hlk |
DropDownList | ddl |
ListBox | lst |
DataList | dtl |
CheckBox | chb |
RadioButton | rdb |
Image | img |
Panel | pnl |
PlaceHolder | phd |
Table | tbl |
Page | Pge |
Frame | fra |
Form | Frm |
Link | Lnk |
Transaction | trn |
Cell | Cll |
Fieldset | fds |
Code Commenting Conventions
All procedures should begin with a brief comment describing what they do. This description should not describe the implementation details. The code itself and any necessary inline comments describe the implementation. Arguments passed to a procedure should be described when their purpose is not obvious and when the procedure expects the arguments to be in a specific range. Return values for functions and variables that are changed by a procedure, especially through reference arguments, should also be described at the beginning of each procedure. Procedure header comments might include the following section headings. For examples, see the “Formatting Your Code” section that follows.
Section Heading | Comment Contents |
Purpose | What the procedure does (not how). |
Assumptions | List of any external variable, control, or other element whose state affects this procedure. |
Effects | List of the procedure’s effect on each external variable, control, or other element. |
Inputs | Explanation of each argument that is not obvious. Each argument should be on a separate line with inline comments. |
Return Values | Explanation of the value returned. |
Author | Name of the person who wrote the function |
Date | Date of written |
- Variables, controls, and procedures should be named clearly to ensure that inline comments are only needed for complex implementation details.
- At the beginning of script, should include an overview that describes the script, enumerating objects, procedures, algorithms, dialog boxes, and other system dependencies. Sometimes a piece of pseudocode describing the algorithm can be helpful.
- Write comments wherever required. Do not write comments for every line of code and every variable declared.
- If you have to use some complex or weird logic for any reason, document it very well with sufficient comments.
- Perform spelling check on comments and also make sure proper grammar and punctuation is used.
Formatting the Code
Screen space should be conserved as much as possible, while still allowing code formatting to reflect logic structure and nesting. Here are a few suggestions:
- Indent standard nested blocks four spaces.
- Indent the overview comments of a procedure one space.
The following code adheres to C# Script coding conventions.
‘*********************************************************
‘Purpose: It will display the string in the message box
‘Inputs: The string needs to be display
‘Returns: It will not return any values
‘Author: Lakshmi Priya
‘Date: 20/Jan/2011
‘*********************************************************
public class SampleRuntimeObject
{
private string fText = “”;
public string Text
{
get
{
return fText;
}
set
{
fText = value;
}
}
public void ShowText ()
{
MessageBox.Show(fText);
}
}
Change History
If the function or procedure is modified it should contain the following details
Date | History | Reason |
April 2011 | Modified several sections. | Information enhancement. |
Pascal and Camel Casing
The terms Pascal Casing and Camel Casing are used throughout this document.
Pascal Casing – First character of all words are Upper Case and other characters are lower case.
Example: BackColor
Camel Casing – First character of all words, except the first word are Upper Case and other characters are lower case.
Example: backColor
Use Pascal casing for Class names
public class HelloWorld
{
…
}
Use Pascal casing for Method names
void SayHello(string name)
{
…
}
Use Camel casing for variables and method parameters
int totalCount = 0;
void SayHello(string name)
{
string fullMessage = “Hello ” + name;
…
}
- Use the prefix “I” with Camel Casing for interfaces
Example: IEntity
- Do not use Hungarian notation to name variables.
Example:
string m_sName;
int nAge;
- Use Meaningful, descriptive words to name variables. Do not use abbreviations.
Example:
string address
int salary
Should not use abbreviations.
Example:
string nam
string addr
int sal
- Do not use single character variable names like
i, n, s etc. Use names like index, temp
- One exception in this case would be variables used for iterations in loops:
for ( int i = 0; i < count; i++ )
{
…
}
- If the variable is used only as a counter for iteration and is not used anywhere else in the loop, it should be in suitable name.
- Do not use underscores (_) for local variable names.
- All member variables must be prefixed with underscore (_) so that they can be identified from other local variables.
- Do not use variable names that resemble keywords.
- Prefix boolean variables, properties and methods with “is” or similar prefixes.
Ex: private bool _isFinished
- Namespace names should follow the standard pattern
<company name>.<product name>.<top level module>.<bottom level module>
- File name should match with class name.
For example, for the class HelloWorld, the file name should be helloworld.cs (or, helloworld.vb)
- Use Pascal Case for file names.
Indenting and Spacing
- Use TAB for indentation. Do not use SPACES. Define the Tab size as 4.
- Comments should be in the same level as the code (use the same level of indentation).
Example:
// Format a message and display
string fullMessage = “Hello ” + name;
DateTime currentTime = DateTime.Now;
string message = fullMessage + “, the time is : ” + currentTime.ToShortTimeString();
MessageBox.Show ( message );
- Curly braces ( {} ) should be in the same level as the code outside the braces.
- Use one blank line to separate logical groups of code.
Example:
bool SayHello ( string name )
{
string fullMessage = “Hello ” + name;
DateTime currentTime = DateTime.Now;
string message = fullMessage + “, the time is : ” + currentTime.ToShortTimeString();
MessageBox.Show ( message );
if ( … )
{
// Do something
// …
return false;
}
return true;
}
- There should be one and only one single blank line between each method inside the class.
- The curly braces should be on a separate line and not in the same line.
Example:
if ( … )
{
// Do something
}
- Use a single space before and after each operator and brackets.
Example:
if ( showResult == true )
{
for ( int i = 0; i < 10; i++ )
{
//
}
}
- Keep private member variables, properties and methods in the top of the file and public members in the bottom.
- Use #region to group related pieces of code together. If we use proper grouping using #region, the page should like this when all definitions are collapsed.
Good Programming Practices
- A method should typically have 1~25 lines of code. Method name should tell what it does. Do not use mis-leading names.
- A method should do only ‘one job’. Do not combine more than one job in a single method, even if those jobs are very small.
- Use the c# specific types (aliases), rather than the types defined in System namespace.
int age; (not Int16)
string name; (not String)
object contactInfo; (not Object)
- Do not hardcode numbers. Use constants instead. Declare constant in the top of the file and use it in your code.
- Do not hardcode strings. Use resource files.
- Convert strings to lowercase or upper case before comparing. This will ensure the string will match even if the string being compared has a different case.
- Avoid using member variables. Declare local variables wherever necessary and pass it to other methods instead of sharing a member variable between methods.
- Use enum wherever required. Do not use numbers or strings to indicate discrete values.
- Do not make the member variables public or protected. Keep them private and expose public/protected Properties.
- The event handler should not contain the code to perform the required action. Rather call another method from the event handler.
- Do not programmatically click a button to execute the same action you have written in the button click event. Rather, call the same method which is called by the button click event handler.
- Do not hardcode a path or drive name in code. Get the application path programmatically and use relative path.
- Don’t assume that our code will run from drive “C:”. You may never know, some users may run it from network or from a “Z:”.
- Error messages should help the user to solve the problem. Give specific messages like “Failed to update database. Please make sure the login id and password are correct.” Show short and friendly message to the user.
- Avoid having very large files.
- Avoid public methods and properties, unless they really need to be accessed from outside the class. Use “internal” if they are accessed only within the same assembly.
- Avoid passing too many parameters to a method. If you have more than 4~5 parameters, it is a good candidate to define a class or structure.
- If you are opening database connections, sockets, file stream etc, always close them in the finally block. This will ensure that even if an exception occurs after opening the connection, it will be safely closed in the finally block.
- Declare variables as close as possible to where it is first used. Use one variable declaration per line.
Exception Handling
- Do not hide an exception. Always catch only the specific exception, not generic exception.
Example:
void ReadFromFile ( string fileName )
{
try
{
// read from file.
}
catch (FileIOException ex)
{
// log error.
// re-throw exception depending on your case.
throw;
}
}
- When you re throw an exception, use the throw statement without specifying the original exception. This way, the original call stack is preserved.
Example:
catch
{
// do whatever you want to handle the exception
throw;
}
- Do not write try-catch in all your methods. Use it only if there is a possibility that a specific exception may occur and it cannot be prevented by any other means. Do not write very large try-catch blocks.
Conclusion
The scripts and functions will be developed based on the coding standards. It will be helpful to easy maintenance for already existing scripts.