Good code is self-explanatory, readable, optimized, and easy to maintain. Your piece of code should be readable enough and easy to understand like a story. Naming conventions play a major role in this.
Naming Conventions
There are following three terminologies are used to declare C# naming standards.
- Camel Case (camelCase): In this standard, the first letter of the word is always in small letters and after that, each word starts with a capital letter or the first character of every word is UpperCase and other characters are lower case.
- Pascal Case (PascalCase): Using this convention, the first letter of every word needs to be in capital letters.
- Underscore Prefix (_underScore): For underscore ( _ ), the word after underscore(_) uses camelCase terminology.
- Class names and method names should be in Pascal case
- For better indentation and readability, use curly brackets vertically.
- Method arguments and local variables should be in the camelcase.
- Do not use shorthand notation for variable names
- Avoid underscores while naming identifiers.
- Do not use single char variable names like i, t, etc.
- Prefer to use predefined data types over system-defined data types.
- Always Prefix an Interface with a letter I.
- Declare member variables at the top with static variables at the very top.
- Avoid unnecessary comments
- Keep methods short. Max 20-25 lines
- Avoid too many parameters
- Consider warnings as errors
- Minimize the number of return
- The filename should match with the class name and the file name should be in Pascal case
- Prefix boolean variables, properties, and methods with is. For example:
private bool isFinished - Use tab for indentation. The default size is 4
- Comments should be on the same level as of code
- One blank line between methods in a class
Decide between Value Types and Reference Types
In the below C# code, we are passing the variable “i” as value type and in the method, incrementing it by 10. As it was passed by value, you will see the original value “5” as the output of the program code.
static void Main(string[] args)
{
int i = 5;
SetValues(i);
System.Console.WriteLine("Currently i = " + i); // will print "Currently i = 5"
}
static void SetValues(int x)
{
x += 10;
}
In the below code, as we are sending “i” as a reference, it will change the original value of “i” inside the method and hence you will see 15 as the output on the screen.
static void Main(string[] args)
{
int i = 5;
SetValues(ref i);
System.Console.WriteLine("Currently i = " + i); // will print "Currently i = 15"
}
static void SetValues(ref int x)
{
x += 10;
}
Hence, decide before you start the implementation, else once implemented it will be very difficult to change them over your huge application.
Always Use Properties instead of Public Variables
public class Person
{
public string Name { get; private set; }
public string Age { get; }
}
If you don’t want anybody to set the Property explicitly from outside, you can just only implement the getter inside the property implementation or mark the setter as private. Also, you can implement the properties from any interface, thus giving you more OOPs.
Use Nullable Data Types Whenever Required
int index = 0; // simple declaration of int
To convert this as a nullable data type, you have to modify a bit to declare like this:
int? index = null; // nullable data type declaration
Once you add the “?” modifier to the data type, your variable will become nullable and you will be able to store “null” value to it. Generally, it is helpful when used with boolean values.
Prefer Runtime Constants over Compile time Constants
Runtime constants are the one which is evaluated at the runtime and are declared using the keyword “readonly”. While compile-time constants are static and evaluated at the compilation time and declared using the keyword “const”.
public readonly string CONFIG_FILE_NAME = “web.config”; // runtime constant
public const string CONFIG_FILE_NAME = “web.config”; // compile time constant
Prefer string.Format() or StringBuilder for String Concatenation
Using string.format() will not create multiple objects but will create a single one. StringBuilder is an immutable object that does not create separate memory for every operation. Hence, it is recommended to do such operations by using either string.Format() or StringBuilder.
string str = string.Format(“{0}{1}{2}{3}{4}”, “k”, “u”, “n”, “a”, “l”);
If you want to use StringBuilder, here is the code for you:
StringBuilder sb = new StringBuilder();
sb.Append("k");
sb.Append("u");
sb.Append("n");
sb.Append("a");
sb.Append("l");
string str = sb.ToString();
foreach(var collectionValue in MyCollection)
{
// your code
}
Here, if your MyCollection is an Array type, the C# compiler will generate the following code for you:
for(int index = 0; index < MyCollection.Length; index++)
{
// your code
}
Properly Utilize try/catch/finally Blocks
Yes, properly utilize the try/catch/finally blocks. If you know that the C# code you wrote may throw some Exception, use the try/catch block for that piece of code to handle the exception. If you know that, the fifth line of your 10 lines code may throw an exception, it is advisable to wrap that line of code only with the try/catch block. Unnecessary lines of code with try/catch slow down your code processing. Sometimes, I notice people surrounding every method with try/catch blocks which is really very bad and decreases the performance of the code. So from now, use it only when it is required. For cleaning up of resources use the finally block after the call. If you are calling any database, close the connection in that block. Whether your code executes properly or not, the finally block always runs. So, properly utilize it to clean up the resources.
Catch Only that Exception that You Can Handle
It is also a major one. We always use the generic Exception class to catch any exception which is neither good for your application nor for the system performance. Use catch on those which are expected and order them accordingly. At the end of the code, add the generic Exception to catch any other unknown exceptions. This gives you a proper way to handle the exception. Suppose, your code is throwing NullReferenceException or ArgumentException.Direct use of the Exception class is very difficult to handle in your application. You can handle the problem easily, by catching the exception properly,
Use IDisposable Interface
Use IDisposable interface to free all the resources from the memory in C#. Once you implement an IDisposable interface in your class, you will get a Dispose() method there. Write code there to free the resources. If you implement IDisposable, you can initialize your class like this:
using (PersonDataSource personDataSource = DataSource.GetPerson())
{
// write your code here
}
After the using() {} block, it will call the Dispose() method automatically to free up the class resources. You will not have to call the Dispose() explicitly for the class.
Splitting of Logic into Several Small and Simple Methods
If methods are too long, sometimes it is difficult to handle them. Always use a number of small methods based upon their functionality instead of putting them in a single one. If you break them in separate methods and in the future you need to call one part, it will be easier to call rather than replicating the code. Also, it is easier to do unit testing for the small chunks rather than a big C# code. So, whenever you are writing a piece of code, first think of what you want to do and extract your code in small simple methods and call them from wherever you want. In general, a method should not exceed 10-15 lines long.
Microsoft Windows 10 is a widely used operating system in computers all over the world. If you have skills in Microsoft Windows 10 then you can get a Windows 10 Certification from StudySection which can help you in getting hired. A beginner level certification exam for newbies and an advanced level certification exam for experts is available on StudySection.