C# Coding Guideline
C# is a general-purpose, modern and object-oriented programming language pronounced as “C Sharp”. It was developed by Microsoft led by Anders Hejlsberg and his team within the .NET initiative and was approved by the European Computer Manufacturers Association (ECMA) and International Standards Organization (ISO). C# is among the languages for Common Language Infrastructure. C# is a lot similar to Java syntactically and is easy for users who have knowledge of C, C++, or Java.
Below are some of the best practices which all the .Net Developers should follow:
- Class and Method names should always be in Pascal Case
public class Employee
{
public Employee GetDetails()
{
//...
}
public double GetBonus()
{
//...
}
}
- Method argument and Local variables should always be in Camel Case
public class Employee
{
public void PrintDetails(int employeeId, String firstName)
{
int totalSalary = 2000;
// ...
}
}
- Avoid the use of underscore while naming identifiers
// Correct
int employeeId;
string employeeName;
bool isActive;
// Avoid
Int32 employee_id;
String employee_name;
Boolean is_active;
- Always prefix an interface with letter I.
// Correct
public interface IEmployee
{
}
public interface IShape
{
}
public interface IAnimal
{
}
// Avoid
public interface Employee
{
}
public interface Shape
{
}
public interface Animal
{
}
- For better code indentation and readability always align the curly braces vertically.
// Correct
class Employee
{
static void PrintDetails()
{
}
}
// Avoid
class Employee
{
static void PrintDetails()
{
}
}
- Always use the using keyword when working with disposable types. It automatically disposes the object when program flow leaves the scope.
using(var conn = new SqlConnection(connectionString))
{
// use the connection and the stream
using (var dr = cmd.ExecuteReader())
{
//
}
}
- Always declare the variables as close as possible to their use.
// Correct
String firstName = "Shubham";
Console.WriteLine(firstName);
//--------------------------
ExampleFunction();
AnotherFunction();
AnotherBusinessLogic();
// Avoid
String firstName = "Shubham";
ExampleFunction();
AnotherFunction();
AnotherBusinessLogic();
Console.WriteLine(firstName);
- Always declare the properties as private so as to achieve Encapsulation and ensure data hiding.
// Correct
private int employeeId { get; set; }
// Avoid
public int employeeId { get; set; }
- Always seperate the methods, different sections of program by one space.
// Correct
class Employee
{
private int employeeId { get; set; }
public void PrintDetails()
{
//------------
}
}
// Avoid
class Employee
{
private int employeeId { get; set; }
public void PrintDetails()
{
//------------
}
}
- Constants should always be declared in UPPER_CASE.
// Correct
public const int MIN_AGE = 18;
public const int MAX_AGE = 60;
// Avoid
public const int Min_Age = 18;
public const int Max_Age = 60;
- Use singular names for enums. Exception: bit field enums.
// Correct
public enum Color
{
Red,
Green,
Blue,
Yellow,
Magenta,
Cyan
}
// Exception
[Flags]
public enum Dockings
{
None = 0,
Top = 1,
Right = 2,
Bottom = 4,
Left = 8
}
// Avoid
public enum Cars //Plural
{
Bugatti,
Ferrari,
Ford,
Audi,
BMW
}
- Naming Convention Examples
Language element |
Casing |
Example |
Namespace |
Pascal |
System.Drawing |
Type parameter |
Pascal |
TView |
Interface |
Pascal |
IBusinessService |
Class, struct |
Pascal |
AppDomain |
Enum |
Pascal |
ErrorLevel |
Enum member |
Pascal |
FatalError |
Resource key |
Pascal |
SaveButtonTooltipText |
Constant field |
Pascal |
MaximumItems |
Private static readonly field |
Pascal |
RedValue |
Private field |
Camel |
listItem |
Non-private field |
Pascal |
MainPanel |
Property |
Pascal |
BackColor |
Event |
Pascal |
Click |
Method |
Pascal |
ToString |
Local function |
Pascal |
FormatText |
Parameter |
Camel |
typeName |
Tuple element names |
Pascal |
(string First, string Last) name = ("John", "Doe"); var name = (First: "John", Last: "Doe"); (string First, string Last) GetName() => ("John", "Doe"); |
Variables declared using tuple syntax |
Camel |
(string first, string last) = ("John", "Doe"); var (first, last) = ("John", "Doe"); |
Local variable |
Camel |
listOfValues |
Note: in case of ambiguity, the rule higher in the table wins.
- Use string interpolation to concatenate short strings, as shown in the following code.
string displayName = $"{nameList[n].LastName}, {nameList[n].FirstName}";
- To append strings in loops, especially when you are working with large amounts of text, use a StringBuilder object.
var phrase = "lalalalalalalalalalalalalalalalalalalalalalalalalalalalalala";
var manyPhrases = new StringBuilder();
for (var i = 0; i < 10000; i++)
{
manyPhrases.Append(phrase);
}
//Console.WriteLine("tra" + manyPhrases);
public Form2()
{
// You can use a lambda expression to define an event handler.
this.Click += (s, e) =>
{
MessageBox.Show(
((MouseEventArgs)e).Location.ToString());
};
}
var localDistributors =
from customer in customers
join distributor in distributors on customer.City equals distributor.City
select new { Customer = customer, Distributor = distributor };
C Coding Guideline
This document is prepared to help developers about how to write the code. It contains different types of code language rules. These rules make writing, maintaining, reviewing the code easier. Also some rules increase portability, …
Horizontal Spacing
Tab usage with space
In most projects, we are using number of spaces instead of using the tab character(\t). Most cases 4 spaces could be use for tab key. This can be set from settings of most IDE’s.
Unary Operators
The unary operators are written with no space between the operator and the operand.
!value
~bits
++i
j--
(CPU_INT32U)x
*ptr
&x
sizeof(x)
Binary Operators
The binary operators (and the ternary operator) are written with at least on space between the operator and operands.
c1 = c2;
x + y
i += 2;
n > 0 ? n : -n
a < b
c >= 2
Expressions
Expressions within parentheses are written with no space after the opening parenthesis and no space before the closing parenthesis.
if and if-else statements
if(x < y)
{
return -1;
}
else if(x > y)
{
return 1;
}
else
{
return 0;
}
while, do-while and for loops
while(condition)
{
}
do
{
} while(condition);
for(int i = 0, j = argc; i < argc; i++, j--)
{
}
switch-case statements
switch(number)
{
case RED:
return GREEN;
case GREEN:
return BLUE;
case BLUE:
return RED;
default:
return BLACK;
}
Naming Convention
In this section, there are some naming convention rules for C language.
These rules can be applied to:
- Public and local functions
- Typedef struct and enumeration
- Public and local variables
Public and Local Functions
Naming convention of functions is important because if there is a good naming for functions, it would be easy to read the code.
Public Functions
Public functions can be called from another files. So it is better to put some prefix before function name:
Example:
void network_stackMgmt(int code);
bool uartIO_txEnable(void);
Local Functions
Local functions can be called only from inside the file that the function is written. So there is no need to put a prefix before function name:
static void clearBuffer(void);
static bool getState(int index);
Typedef Struct and Enumeration
Naming convention of typedef structures and enumerations is important because if there is a good naming, it would be easy to read the code.
Struct
If there is a good naming for the structure definition, it would be easy to read the code.
struct s_deviceManagerRing {
uint8 link;
char mac[18];
};
Typedef Struct
If there is a good naming for the typedef structure definition, it would be easy to read the code.
typedef struct {
uint64_t mac;
char ipServer[48];
uint16_t portServer;
uint16_t portClient;
} ts_gsmNet;
Enumeration
İf there is a good naming for the enumeration definition, it would be easy to read the code.
enum e_deviceManagerStates {
E_DEVICE_MANAGER_INIT = 0,
E_DEVICE_MANAGER_START,
E_DEVICE_MANAGER_STOP,
};
Typedef Enumeration
If there is a good naming for the typedef enumeration definition, it would be easy to read the code.
typedef enum {
E_DIO_E_INPUT_1 = 0,
} te_dioInputs;
Public and Local Variables
Naming convention of variables is important because if there is a good naming for variables, it would be easy to read the code.
Public Variables
Public variables can be used from another files. So it is important to have a prefix before the variable name like this:
char uartIO_respReady[6] = "READY";
char lon_respSet[6] = "SET\r\n";
Local Variables
Local variables can be used from only the file that they are written inside. So it is not important to have a prefix before the variable name.
static bool up;
static uint64_t local;
static uint8_t button;
File Content
It is better to have sections inside the file in every coding language. In this section there are some rules about file content.
File content should be separated with some comment blocks. So this way, it would be easy to find what we are looking for in the file content.
To get a documentation from the comments, Doxygen format is used for comments.
This section is prepared to give some information about doxygen comment blocks and how to write them.
Function Documentation
Here is one example:
/**
* \brief Initializes the UART handle.
* \param config UART configuration string (ex. "COM1:115200,N,8,1")
* \return Returns a handle to the newly opened UART
*/
UART_HandleTypeDef *uartOpen(char *config)
{
...
}
Variable Documentation
Here is one example:
static uint8 mode[2]; /**< Uart mode * /
Define Documentation
Here is one example:
/* UART configuration */
#define UARTIO_EVEN FALSE /**< Even parity */
#define UARTIO_PARITY FALSE /**< Parity enabled */
#define UARTIO_WORDLEN E_AHI_UART_WORD_LEN_8 /**< Word length */
#define UARTIO_ONESTOP TRUE /**< One stop bit */
File Heading
A comment block must be placed at the beginning of each source code file (both code and header files) containing;
- Filename
- Brief(short description)
- Details(detailed description)
- Remarks(additional remarks)
Here is one example comment block:
/**
* \file Filename
* \brief A brief description, one sentence, one line.
* \details A detailed description of the file scope, it can span over
* multiple lines, can be omitted.
* \remarks Additional remarks.
*/
File Layout
Both source and header files must be divided by sections:
- INCLUDE FILES
- MACRO DEFINITIONS
- LOCAL DATA TYPES
- LOCAL CONSTANTS
- VARIABLES
- LOCAL FUNCTION PROTOTYPES
- PUBLIC FUNCTION
- LOCAL FUNCTION
Even if the section is empty, it’s comment block must be added to the file:
/*----------------------------< Section Name >--------------------------*/
Include Section
The INCLUDE FILES section should include all necessary header files.
/*------------------------------< Includes >-----------------------------*/
#include <iostream>
#include <thread>
Macro Definitions Section
The MACRO DEFINITIONS section should include all necessary macro defines.
/*--------------------------< Macro Definitions >-----------------------*/
#ifndef TRACE_APP
#define TRACE_APP TRUE
#endif
Local Constants Section
The LOCAL CONSTANTS section should include all necessary constant variables.
/*--------------------------< Constants >-------------------------------*/
const uint32 msecCount = 1800;
Local Data Types Section
The LOCAL DATA TYPES section should include all necessary data type definitions.
/*----------------------------< Typedefs >-------------------------------*/
typedef struct
{
bool rts; /**< Current RTS setting */
bool cts; /**< Current CTS setting */
} ts_uart;
Local Variables Section
The LOCAL VARIABLES section should include all necessary local(static) variables.
/*---------------------------< Variables >------------------------------*/
static uint8 uart = APP_UART_0;
Local Function Prototypes Section
The LOCAL FUNCTION PROTOTYPES section should include all necessary local(static) function prototypes.
/*-------------------------< Prototypes >-----------------------------*/
static void delayMsec(uint32 period);
Public Function Section
The PUBLIC FUNCTION section should include all necessary public function declarations.
/*---------------------------< Public Function >------------------------*/
void dio_outputInitialise(void)
{
...
}
Local Functions Section
The LOCAL FUNCTION section should include all necessary local(static) function declarations.
/*-------------------------< Private Function >--------------------------*/
static void initialiseApp(void)
{
...
}
Abbreviations
Please refer to here to see abbreviations.