RuleDescriptionExampleKPI
CatchBlocksShouldRethrowAny catch block should rethrow or throw and not eat exceptions.Cause:
A Catch block that does don't throw any exception is not recommended.


Non-complaint Code:

try
{
// do something
}
catch
{
}


Complaint Code:

try
{
// do something
}
catch (Exception ex)
{
throw;
}

Analyzability
CompilerWarningLevelIsSetTooLowBuild with the highest warning levelCause:
Warnings are potential problems with your code. Turning on the warnings at the highest level will highlight these problems, allowing you to fix them //early, rather than let them become potential bugs at a later date.


Complaint Code:

You can change the warning level for a project by right-clicking on it, going to its properties page and then setting warning level to highest ie.4 on its Build tab.
Understandability
DisposeFieldsProperlyThis class has a disposable field and is not disposing it.Non-Complaint Code:

internal class D : System.IDisposable
{
}
class Class1
{
private D field = D.Open();
}


Compliant code:
class Class1 : System.IDisposable
{
private D field = D.Open();

public void Dispose()
{
field.Dispose();
}
}

Maintainability
DoNotHideInheritedMembersOn hiding an inherited member, the derived version of the member replaces the base class versionCause:
Using a new keyword for a base class member in the derived class, hides the base class member. Ensure the required functionality and look out for compiler warnings. To simply put, if a method is not hiding the base method, it should be overriding it.

Complaint code:
public class B
{
public virtual void M(int i)
{
}
}

public class C : B
{
public new void M(int i)
{
}
}



Non-compliant code:
public class B
{
public virtual void M(int i)
{
}
}

public class C : B
{
public override void M(int i)
{
}
}
Understandability
DoNotPrefixLocalCallsWithThisKeyword A call to an instance member of the local class or a base class is prefixed with ‘this’. Non-compliant code:
class Employee
{
public string FirstName;
public string LastName;
public string Salary;

public void SetName(
string newFirstName, string newLastName)
{
this.FirstName = newFirstName;
this.LastName = newLastName;
}
}


Compliant code:
class Employee
{
public string FirstName;
public string LastName;
public string Salary;

public void SetName(
string newFirstName, string newLastName)
{
FirstName = newFirstName;
LastName = newLastName;
}
}

Understandability
FieldsMustBePrivateMake the field private and add a property to expose the field outside of the classCause:
A violation of this rule occurs whenever a field in a class is given non-private access. For maintainability reasons,
//properties should always be used as the mechanism for exposing fields outside of a class, and fields should always be
//declared with private access. This allows the internal implementation of the property to change over time without changing
//the interface of the class.

Issue occurence:

Fields located within C# structs are allowed to have any access level.

Solution:

To fix a violation of this rule, make the field private, and add a property to expose the field outside of the class.
Maintainability
HardCodedStringsAndMagicNumbersHard coded values should be moved to resources for better maintainabilityCause:
For better maintainability of code it is recommended to have all strings in one place and you only need to change it there to update the whole program.

Non-complaint code:

public void MyMethod()
{
if (s != “some hard-coded value”)
{
}
}


Compliant code:

public void MyMethod()
{
if (s.Equals(Resources.SomeValue))
{
}
}
Maintainability
MakeLocalVariableConstant If a variable is assigned a constant value and never changed, it can be made ‘const’Cause:
The variable is assigned a constant value and never changed, it can be made a const

Non-compliant code:

class Class1
{
int Method1()
{
int x = 30;

return x;
}
}


Compliant code:
class Class1
{
int Method1()
{
const int x = 30;

return z;
}
}
Maintainability
RedundantFieldAssignmentConsider not assigning the default value to a field for performance optimisationCause:
It’s recommended not to assign the default value to a field as a performance optimization.

Non-complaint code:

class SampleClass
{
private int number = 0;
// …
}



Complaint code:
class SampleClass
{
private int number;
// …
}
Efficiency
ThrowDoesNothingIf an exception is caught and then thrown again the original stack trace will be lost. It is best to throw an exception without using any parametersCause:
Throwing the same exception as passed to the ‘catch’ block lose the original stack trace and will make debugging this exception a lot more difficult. The correct way to rethrow an exception without changing it is by using ‘throw’ without any parameter.

Non-complaint code:
try { }
catch (System.Exception ex)
{
throw ex;
}


Complaint code:
You will have two choices, you can rethrow the original exception as-is:

try { }
catch (System.Exception ex)
{
throw;
}

//Or you can rethrow the original exception as an inner exception, like so:

try { }
catch (System.Exception ex)
{
throw new Exception(“some reason to rethrow”, ex);
}
Analyzability
UseConfigureAwaitFalseOnAwaitedTaskConsider using ConfigureAwait(false) on the awaited taskNon-complaint code:

public async Task TestAsync()
{
await GetValueAsync(); // RCS1090
}


Complaint code:
public async Task TestAsync()
{
await GetValueAsync().ConfigureAwait(false);
}
Robustness
UseOfRegexIsMatchMightBeImprovedInstantiating the Regex object multiple times might be bad for performance. Consider using the static IsMatch method from Regex class and/or compile the regexCause:
When IsMatch() method is called multiple times, you should be using the static Regex.IsMatch method, as that can be cached and won’t be interpreted //every time you call the method, it will give you better performance.


Non-complaint code:

public static bool TestRegex(string parameterValue)
{
string pattern = @”p{Sc}+s*d+”;
Regex test = new Regex(pattern);
return test.IsMatch(parameterValue);
}


Complaint code:
public static bool TestRegex(string parameterValue)
{
string pattern = @”p{Sc}+s*d+”;
return Regex.IsMatch(parameterValue, pattern);
}
Efficiency
UseStaticMethodIf the method is not referencing any instance variable and if you are not creating a virtual/abstract/new or partial method and if it is not an overridden method, your instance method can be changed to a static method.Non-complaint code:

public class Program
{
public int calculation(int x, int y)
{
int val = x * y;
return val;
}
static void Main(string[] args)
{
Program obj = new Program();
int result = obj.calculation(18, 14);
Console.WriteLine(result);
Console.ReadKey();
}
}


Complaint code:
public class Program
{
public static int calculation(int x, int y)
{
int val = x * y;
return val;
}
static void Main(string[] args)
{
int result = calculation(18, 14);
Console.WriteLine(result);
Console.ReadKey();
}
}
Robustness
UseSwitchMultiple ‘if’ and ‘else if’ statements can be replaced with a ‘switch’Cause
In a switch statement, all elements get the same access time, compared to a list of if-else’s where the last element takes much more time to reach as //it has to evaluate every previous condition first. Thus the compiler is better in optimizing a switch-statement than an if-statement.

Non-complaint code:

public void DoThis(string s)
{
if (s == “A”)
{
// ..
}
else if (s == “B”)
{
// ..
}
else if (s == “C”)
{
// ..
}
else
{
// ..
}
}


Complaint code:
public void DoThis(string s)
{
switch (s)
{
case “A”:
break;
case “B”:
break;
case “C”:
break;
default:
break;
}
}
Efficiency
LogErrorInCatchThe log level inside Catch block should be ErrorCause
A log level less than an Error is not recommended within a Catch Block especially when there is an exception.

Non-complaint code:

try
{
var testVar = 10/0;
}
catch (Exception e)
{
log.Info("Divide by zero exception occured");
}


Non-complaint code:
try
{
var testVar = 10/0;
}
catch (Exception e)
{
log.Error("Divide by zero exception occured");
}
Maintainability