Sunday, June 12, 2011

C# Coding Standards and Best Programming Practices

Do you want to become the 'Most Valued Professional' of your company? Writing 'Efficient Code' is an art and you must learn and practice it.

Naming Conventions and Standards

Note :
Pascal Casing - First character of all words are Upper Case and other characters are lower case.
Camel Casing - First character of all words, except the first word are Upper Case and other characters are lower case.
·  Use Pascal casing for Class names
public class HelloWorld
{
       ...
}

·  Use Pascal casing for Method names
public class HelloWorld
{
       void SayHello(string name)
       {
              ...
       }
}
·  Use Camel casing for variables and method parameters
public class HelloWorld
{
       int totalCount = 0;
       void SayHello(string name)
       {
              string fullMessage = "Hello " + name;
              ...
       }
}
·  Do not use Hungarian notation to name variables.

In earlier days most of the programmers liked it - having the data type as a prefix for the variable name and using m_ as prefix for member variables. Eg:
 
string m_sName;
int nAge;
 
However, in .NET coding standards, this is not reccommended. Usage of datatype and M_ to represent member variables should not be used. All variables should use camel casing.
·  Use Meaningfull, descriptive words to name variables.

- Do not use abbreviations. Use
name, address, salary etc instead of nam, addr, sal
- Do not use single character variable names like
i, n, x 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, many people still like to use a single char variable (i) instead of inventing a different suitable name.
- Do not use underscores (_) in variable names.
- 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)

Indentation and Spacing

·  Use TAB for indentation. Do not use SPACES.
·  Comments should be in the same level as the code.
·  Curly braces ( {} ) should be in the same level as the code outside teh braces.
·  Use one blank line to separate logical groups of code.
       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;
       }
This code looks better, than the code shown above:
       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 adn not in the same line as if, for etc.
Good:
              if ( ... )    
              {
                    // Do something
              }
Not Good:
              if ( ... )    {
                    // Do something
              }
·  Use a single space before and after each operator and brackets.

Good:
              if ( showResult == true )
              {
                    for ( int i = 0; i < 10; i++ )
                    {
                           //
                    }
              }
Not Good:
              if(showResult==true)
              {
                    for(int       i= 0;i<10;i++)
                    {
                           //
                    }
              }

Good Programming practices


Follow the best practices to for best programming
·  Avoid having too large files. If a file has more than 300~400 lines of code, you must consider refactoring code into helper classes.
·  Avoid writing very long methods. A method should typically have 1~25 lines of code. If a method has more than 25 lines of code, you must consider re factoring into separate methods.
·  Method name should tell what it does. Do not use mis-leading names. If the method name is obvious, there is no need of documentation explaining what the method does.

Good:
       void SavePhoneNumber ( string phoneNumber )
       {
              // Save the phone number.
       }

Not Good:
       // This method will save the phone number.
       void SaveData ( string phoneNumber )
       {
              // Save the phone number.
       }
·  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.

Good:
       // Save the address.
       SaveAddress (  address );
       
       // Send an email to the supervisor to inform that the address is updated.
       SendEmail ( address, email );            
       
       void SaveAddress ( string address )
       {
              // Save the address.
              // ...
       }
       
       void SendEmail ( string address, string email )
       {
              // Send an email to inform the supervisor that the address is changed.
              // ...
       }

Not Good:
       // Save address and send an email to the supervisor to inform that the address is updated.
       SaveAddress ( address, email );
 
       void SaveAddress ( string address, string email )
       {
              // Job 1.
              // Save the address.
              // ...
 
              // Job 2.
              // Send an email to inform the supervisor that the address is changed.
              // ...
       }
·  Use the c# or VB.NET specific types, rather than the alias types defined in System namespace.

Good:
       int age;
       string name;
       object contactInfo;

Not Good:
       Int16 age;
       String name;
       Object contactInfo;
       
·  Do not hardcode numbers. Use constants instead.
·  Do not hardcode strings. Use resource files.
·  Avoid using many member variables. Declare local variables and pass it to methods instead of sharing a member variable between methods. If you share a member variable between methods, it will be difficult to track which method changed the value and when.
·  Use enum wherever required. Do not use numbers or strings to indicate discrete values.
Good:
       enum MailType
       {
              Html,
              PlainText,
              Attachment
       }
 
       void SendMail (string message, MailType mailType)
       {
              switch ( mailType )
              {
                    case MailType.Html:
                           // Do something
                           break;
                    case MailType.PlainText:
                           // Do something
                           break;
                    case MailType.Attachment:
                           // Do something
                           break;
                    default:
                           // Do something
                           break;
              }
       }


Not Good:
       void SendMail (string message, string mailType)
       {
              switch ( mailType )
              {
                    case "Html":
                           // Do something
                           break;
                    case "PlainText":
                           // Do something
                           break;
                    case "Attachment":
                           // Do something
                           break;
                    default:
                           // Do something
                           break;
              }
       }
·  Do not make the member variables public or protected. Keep them private and expose public/protected Properties.
·  Never hardcode a path or drive name in code. Get the application path programmatically and use relative path.
·  Never assume that your code will run from drive "C:". You may never know, some users may run it from network or from a "Z:".
·  In the application start up, do some kind of "self check" and ensure all required files and dependancies are available in the expected locations. Check for database connection in start up, if required. Give a friendly message to the user in case of any problems.
·  If the required configuration file is not found, application should be able to create one with default values.
·  If a wrong value found in the configuration file, application should throw an error or give a message and also should tell the user what are the correct values.
·  Error messages should help the user to solve the problem. Never give error messages like "Error in Application", "There is an error" etc. Instead give specific messages like "Failed to update database. Please make sure the login id and password are correct."
·  When displaying error messages, in addition to telling what is wrong, the message should also tell what should the user do to solve the problem. Instead of message like "Failed to update database.", suggest what should the user do: "Failed to update database. Please make sure the login id and password are correct."
·  Show short and friendly message to the user. But log the actual error with all possible information. This will help a lot in diagnosing problems.

Comments

·  Do not write comments for every line of code and every variable declared.
·  Write comments wherever required. But good readable code will require very less comments. If all variables and method names are meaningfull, that would make the code very readable and will not need much comments.
·  Less lines of comments will make the code more elegant. But if the code is not clean/readable and there are less comments, that is worse.
·  If you have to use some complex or weired logic for any reason, document it very well with sufficient comments.
·  If you initialize a numeric variable to a special number other than 0, -1 etc, document the reason for choosing that value.
·  The bottom line is, write clean, readable code such a way that it doesn't need any comments to understand.
·  Do a spell check on comments and also make sure proper grammar and punctuation is used.

Exception Handling

·  Never do a 'catch exception and do nothing'. If you hide an exception, you will never know if the exception happened or not.
·  In case of exceptions, give a friendly message to the user, but log the actual error with all possible details about the error, including the time it occurred, method and class name etc.
·  Always catch only the specific exception, not generic exception.

Good:
       void ReadFromFile ( string fileName )
       {
              try
              {
                    // read from file.
              }
              catch (FileIOException ex)
              {
                    // log error.
                    //  re-throw exception depending on your case.
                    throw;
              }
       }
Not Good:
       void ReadFromFile ( string fileName )
       {
              try
              {
                    // read from file.
              }
              catch (Exception ex) 
              {
                    // Catching general exception is bad... we will never know whether it
                    // was a file error or some other error.
                    
                    // Here you are hiding an exception. 
                    // In this case no one will ever know that an exception happened.
 
                    return "";          
              }
       }
·  No need to catch the general exception in all your methods. Leave it open and let the application crash. This will help you find most of the errors during development cycle.
·  You can have an application level (thread level) error handler where you can handle all general exceptions. In case of an 'unexpected general error', this error handler should catch the exception and should log the error in addition to giving a friendly message to the user before closing the application, or allowing the user to 'ignore and proceed'.
·  Do not write try-catch in all your methods. Use it only if there is a possibility that a a specific exception may occur. For example, if you are writing into a file, handle only FileIOException.
·  Do not write very large try-catch blocks. If required, write separate try-catch for each task you perform and enclose only the specific piece of code inside the try-catch. This will help you find which piece of code generated the exception and you can give specific error message to the user.
·  You may write your own custom exception classes, if required in your application. Do not derive your custom exceptions from the base class SystemException. Instead, inherit from ApplicationException.

Object Oriented Programming Concepts (for .NET)

1.variable: A variable is a label or reference to a container in memory that is allocated a name by the programmer.
Numeric,Character,Boolean,Structures,Enumerations
2.const:Constants are like variables except that, once they have been assigned a value, they don't change.
const int ABSOLUTEZERO = -273;
3.array:An array is basically a group of variables of the same type, which are grouped together using a common name and which only differ by an index that is appended to that name, enclosed in square brackets.
string [] myString;
4.struct:Struct like the array, enables to group together related data into a single unit and each contained item can be referenced individually. int,double etc are simple data types, which only represent a single data value. Structs are data types, which contain more than one data value.
  • They can contain data of multiple types,including other complex types
  • They can contain data other than just name-value pairs, such as methods and properties
struct myStruct{public string strName; public double dblDepositPaid;}  //Definition
myStruct myStruct1;   //Declaration, just like data types

5.enum:enum is a user defined complex data type that allows a variable to have a predefined, limited set of values.
enum Gender{Male = 0, Female = 1}
6.param:to set properties to any object
<param name="border" value="1">
7.Function or Method:Functions are mini-programs.If you want to use the same code in more than one place, you use functions. ASP.NET jumps away from the execution of the main body of code, runs through the commands specified in a function and then returns to the task of executing the mian body of code.
8.Passing Parameters by value:(the variable value is Read-only)By default, simple data values are passed to functions by value. This means that when the parameter variables are created inside the function, they are all set up to have the value that was passed in. Effectively, it means that inside a function, we are working with a copy of the original data.
Passing by value means that copy is made for the function to play with, and the value of the original variable in the calling code is left untouched.
Passing Parameters by Reference(ref keyword):(the variable value is Read and Write)When the function call is made, instead of a copy of the variable being taken of the value stored in the variable, the variable in the function is set to 'point' to the same piece of data represented by the variable, that is, a reference to the variable is created in the variable inside the function.
out parameters:(the variable is Write-only)The function itself has a value for the variable so we are just going to read the value from the function itself. In the function call we can change the value of the variable in the function.
9.Event:HTML:onmouseup,onmousedown,onmouseover,onmousemove,onclick,ondblclick,onkeyup,onkeypress,onkeydown,.NET:onLoad, onUnload, onClick/onCommand, onInit,onPrerender,Disposed,DataBinding,SelectIndexChanged,CheckChanged,TextChanged,page_init,page_load,page_unload etc are all events
10.object:An object is simply a bundle of code that describes some sort of real-world object. It might be a physical object(such as a book or a person) or abstract object(like a number). Anything that exists in the real world can be represented in some fashion as a software object.
11.abstraction:When we are defining a class, we don't want to define certain properties of the object. the details that we abstract about an object can be seperated into two main categories:
  • Details that aren't relevant or appropriate to the particular situation we're modeling
  • Details that are implicit, either to the specific situation, or in the functionality that is exposed
12.Encapsulation - The Black Box:When we're using objects, their essential characteristics are what matter, not how they work underneath, which means we have a great deal less to think about. So the process of packaging up functionality in terms of properties and methods in an object by specifying these essential characteristics and behaviors is called encapsulation.
13.visibility(public,private,protected):public  means we'll be able to use it from anywhere in our code.private and protected can be used to restrict the use to specific parts of an application.
14.accessor methods:get and set are two special methods that let us define the code that's used to respectively retrieve values from the private member and set values on it.
15.constructor:Constructors get the objects ready for use and set their data members to sensible values.
Car AlexCar;  //declaration
AlexCar = new Car();  //initialization
The initialization stage of object instantiation is responsible for setting up the object in memory, and will call on a constructor method for that object to do the necessary work.
16.overloaded methods:When we overload an object method, each version should have a different signature(number of parameters or data type)
17.static(shared members):A shared(or static) member is one that operates across all instances of a class. It can be accessed via the object class itself as well as any specific instance of that class.
Two objects can share functionality that is properties and methods. Those properties and methods are called shared members(also called static members).we can define methods and properties that apply to the class as a whole, and not tie to a specific object.
Ex: all constructors methods are shared by definition
18.Association - 'Uses A':one class using another;If an object of class A can perform it's full set of functionality while having absolutely no awareness of class B,we can say that class A does not use class B.
Containment(also composition or aggregation) - A 'Has a' Relationship:When some class A defines a data member of class B, we can say that an object of class A contains an object of class B.
Inheritance - 'Is A':we can define a new class solely in terms of the differences between it and anothe class. Base class and derived class or sub class.
If you can say anything about a bas class A that cannot be said about a proposed subclass B, then B is not really a valid subclass A.

Thursday, June 2, 2011

c# Tips & Trics (Code performance & optimization)

//C sharp Tips1. String string
msg += thisUser.Name;
msg +=
msg += System.DateTime.Now.ToString();
msg = "Hello, ";". Today is ";//we should use the string.Format() methodstring
thisUser.Name, DateTime.Now.ToString( ));
msg = string.Format ( "Hello, {0}. Today is {1}", //For more complicated string operations you can use the StringBuilder classStringBuilder msg =
msg.Append( thisUser.Name );
msg.Append(
msg.Append( DateTime.Now.ToString());new StringBuilder( "Hello, " );". Today is " );string
String
2. For Versus Foreach Performance
--- For loop version [Method1] ---
finalMsg = msg.ToString();static
{


{
a += array[i];
}

}
--- Foreach loop version [Method2] ---
int Method1(int[] array)int a = 0;for (int i = 0; i < array.Length; i++)return a;static
{


{
a += value;
}

}
int Method2(int[] array)int a = 0;foreach (int value in array)return a;using System;using System.Diagnostics;class
{

{

Method1(array);
Method2(array);
var s1 = Stopwatch.StartNew();


{
Method1(array);
}
s1.Stop();
var s2 = Stopwatch.StartNew();

{
Method2(array);
}
s2.Stop();
Console.WriteLine(((
1000000) / m).ToString(
Console.WriteLine(((
1000000) / m).ToString(
Console.Read();
}
}
--- Output ---
7.37 ns
8.04 ns
Results. You can see that the
This
3.--- Program that uses
Programstatic void Main()int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };const int m = 100000000;for (int i = 0; i < m; i++)for (int i = 0; i < m; i++)double)(s1.Elapsed.TotalMilliseconds *"0.00 ns"));double)(s2.Elapsed.TotalMilliseconds *"0.00 ns"));foreach version required slightly more time to execute than the for version. is because the foreach-version uses more local variable space.for-loops on input string [C#] --- using System;class
{

{
Programstatic void Main()string input = "Hi Welcome to India";//// Check each character in the string using for-loop.//

{

{
spaces1++;
}
}
int spaces1 = 0;for (int i = 0; i < input.Length; i++)if (input[i] == ' ')//// BAD: Check each character in the string with ToString calls.//

{
int spaces2 = 0;for (int i = 0; i < input.Length; i++)if (input[i].ToString() == " ") // NO{
spaces2++;
}
}
//// Write results.//Console.WriteLine(spaces1);
Console.WriteLine(spaces2);
}
}
--- Output ---
3
3
--- Benchmark description ---
Iterations: 10000000
Input string: "Hi Welcome to India"Loop bodies: Same
Character testing loop: 46.50 ns
ToString loop: 445.11 ns
Summary: Using ToString was nearly ten times slower.
4.Flattened array
--- Flattened array index computation ---
array[(Y coordinate * width) + X coordinate]
--- 2D array index computation ---
array[Y coordinate, X coordinate]
Example as in top example.while
{
Console.WriteLine(

Console.WriteLine(
(true)"Enter height: [4+]");int height = int.Parse(Console.ReadLine());"Enter width: [10+]");int width = int.Parse(Console.ReadLine());//// A. TWO DIMENSIONAL ARRAY//
int[,] twoDimensional = new int[height, width];// Assign cell 1, 6twoDimensional[1, 6] = 5;
// Assign cell 3, 9twoDimensional[3, 9] = 9;
// Assign cell at 2, 3twoDimensional[2, 3] = 1;
// Display
{

{
Console.Write(twoDimensional[i, a]);
}
Console.WriteLine();
}
Console.WriteLine();
for (int i = 0; i < height; i++)for (int a = 0; a < width; a++)//// B. FLATTENED ARRAY//
int[] oneDimensional = new int[width * height];// Assign cell 1, 6oneDimensional[1 * width + 6] = 5;
// Assign cell 3, 9oneDimensional[3 * width + 9] = 9;
// Assign cell at 2, 3oneDimensional[2 * width + 3] = 1;
// Display
{

{
Console.Write(oneDimensional[i * width + a]);
}
Console.WriteLine();
}
}
for (int i = 0; i < height; i++)for (int a = 0; a < width; a++)

Wednesday, June 1, 2011

(.NET 2.) Dictionary(Of Key, Value) performance trick

What's often overlooked is a performance penalty with this pattern shift. Because of the exception, people will do something like this:
MyClass toReturn;
if(!_myDictionary.ContainsKey(key))
{
toReturn = _myDictionary[key];
}
else
{
toReturn = new MyClass();
}

Pretty obvious code, right? Well, ok, but it has a performance penalty which isn't that obvious: you'll query the key index twice: once in the ContainsKey call and once in the _myDictionary[key] call. If you query your dictionary a lot of times, even if the dictionary is fairly small, it will hurt performance. Better do:

MyClass toReturn = null;
if(!_myDictionary.TryGetValue(key, out toReturn))
{
 toReturn = new MyClass();
}
During profile sessions of my code I found a lot of these misusages in my .NET 2.0

 if (dict.ContainsKey("Key1"))
            dict
["Key1"] = "Value1";
       
else
            dict
.Add("Key1", "Value1");
You can simplify your 4 lines of code to this:

dict["Key1"] = "Value1"; 

Saturday, May 21, 2011

Threading

Threading enables your Visual Basic or C# program to perform concurrent processing so that you can do more than one operation at a time. For example, you can use threading to monitor input from the user, perform background tasks, and handle simultaneous streams of input.
Threads have the following properties:
  • Threads enable your program to perform concurrent processing.
  • The .NET Framework System.Threading namespace makes using threads easier.
  • Threads share the application's resources. For more information, see Using Threads and Threading.
By default, a Visual Basic or C# program has one thread. However, auxiliary threads can be created and used to execute code in parallel with the primary thread. These threads are often called worker threads.

Example :


namespace ConsoleApplication1
{
    public class ServerClass
    {
        // The method that will be called when the thread is started.
        public void InstanceMethod()
        {
            Console.WriteLine(
                "ServerClass.InstanceMethod is running on another thread." + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());


            int x =0;
            for (int i = 0; i < 1000000000; i++)
            {
                x += x;
            }


            // Pause for a moment to provide a delay to make
            // threads more apparent.
            //Thread.Sleep(3000);
            //Thread.CurrentThread.Abort();
            Console.WriteLine(
                "The instance method called by the worker thread has ended. " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
        }


        
    }


    public class Simple
    {
        
        public static void Main()
        {
            Console.WriteLine("Thread Simple Sample");
            DateTime datetime = System.DateTime.Now;
            long elapsedTicks = System.DateTime.Now.Ticks - datetime.Ticks;
            Console.WriteLine(elapsedTicks.ToString());
            for (int i = 0; i < 2; i++)
            {


                ServerClass serverObject = new ServerClass();
                Thread InstanceCaller = new Thread(
                    new ThreadStart(serverObject.InstanceMethod));


                // Start the thread.
                InstanceCaller.Start();


                Console.WriteLine("The Main() thread calls this after "
                    + "starting the new InstanceCaller thread.");
           
            }
            elapsedTicks = System.DateTime.Now.Ticks - datetime.Ticks;
            Console.WriteLine(elapsedTicks.ToString());
            Console.ReadLine();
        }
    }


}


thread pool is a collection of threads that can be used to perform several tasks in the background. This leaves the primary thread free to perform other tasks asynchronously.



 System.Threading.ThreadPool.QueueUserWorkItem(
        new System.Threading.WaitCallback(AnotherLongTask));
ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);